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
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/
-
-
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
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
\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
* Signature: (Lorg/iotivity/base/OcRepresentation;)V\r
*/\r
{\r
delete rep;\r
}\r
-}
\ No newline at end of file
+}\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
* Signature: (Lorg/iotivity/base/OcRepresentation;)V\r
*/\r
#ifdef __cplusplus\r
}\r
#endif\r
-#endif
\ No newline at end of file
+#endif
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")
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;
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)
{
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;
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
if [ ! -d "boost" ]; then
cloneBoost
fi
-
- # Determine the
+
+ # Determine the
TOOLCHAIN=${ANDROID_NDK}/toolchains/${TOOLSET}-${VERSION}/prebuilt/${HOST_ARCH}/bin
OLDPATH=$PATH
+++ /dev/null
-######################################################################
-# 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])
--- /dev/null
+#******************************************************************
+#
+# 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')])
+
+
target_os = env.get('TARGET_OS')
target_arch = env.get('TARGET_ARCH')
src_dir = env.get('SRC_DIR')
-
-env.SConscript('extlibs/cereal/SConscript')
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
cd $sourcedir/tmp
echo `pwd`
-rm -rf ./extlibs/cereal/cereal/.git*
+rm -rf ./extlibs/tinycbor/tinycbor/.git*
# Initialize Git repository
if [ ! -d .git ]; then
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.
*
* 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);
#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
'../../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',
'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')
/**
* @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.
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;
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");
return NULL;
}
+ memcpy(temp, rep->info.payload, rep->info.payloadSize);
// save the payload
clone->info.payload = temp;
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");
return NULL;
}
+ memcpy(temp, rep->info.payload, rep->info.payloadSize);
// save the payload
clone->info.payload = temp;
* @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
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);
* 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_ */
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);
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);
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=");
Serial.print("resourceUri: ");
Serial.println(info->resourceUri);
Serial.print("payload: ");
- Serial.println(info->payload);
+ Serial.println((char*)info->payload);
}
return;
{
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);
}
}
- 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)
{
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;
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)
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");
}
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);
if (NULL != payload)
{
- OIC_LOG_V(DEBUG, TAG, "add data, payload:%s", payload);
coap_add_data(pdu, payloadSize, (const unsigned char *) payload);
}
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");
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);
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));
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;
CADestroyToken(tempToken);
CADestroyEndpoint(tempRep);
+ free(responseData.payload);
tempRep = NULL;
}
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;
CADestroyEndpoint(tempRep);
tempRep = NULL;
}
+ free (responseData.payload);
}
// check return value NULL is passed instead of a valid CAResponseInfo_t address
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;
CADestroyEndpoint(tempRep);
tempRep = NULL;
}
+ free(responseData.payload);
}
// CASelectNewwork TC
######################################################################
provisioning_env.AppendUnique(CPPPATH = [
'../../stack/include',
+ '../../stack/include/internal',
'../../ocrandom/include',
'../../logger/include',
'../../../oc_logger/include',
#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"
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,
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);
return SP_RESULT_SUCCESS;
}
+OCStackResult OCParsePayload(OCPayload** outPayload, const uint8_t* payload, size_t payloadSize);
/**
* Response handler for discovery.
*
}
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");
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;
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 };
* @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);
}
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)
{
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)
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)
{
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)
{
* 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)
{
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);
#include "doxmresource.h"
#include "credresource.h"
#include "oic_malloc.h"
+#include "oic_string.h"
#include "logger.h"
#include "utlist.h"
#include <string.h>
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);
// 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);
{
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));
}
* @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);
/**
--- /dev/null
+//******************************************************************
+//
+// 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
/*** 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
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
* Prepares a JSON string for response.
*/
OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
- char * out,
- uint16_t *remaining,
+ OCDiscoveryPayload* payload,
CATransportAdapter_t adapter);
/**
// 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;
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);
* @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
* @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);
// 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
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.
--- /dev/null
+//******************************************************************
+//
+// 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
+
--- /dev/null
+//******************************************************************
+//
+// 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
OCMethod method,
const char *requestUri,
const OCDevAddr *destination,
- const char *request,
+ OCPayload* payload,
OCConnectivityType connectivityType,
OCQualityOfService qos,
OCCallbackData *cbData,
* @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
OCNotifyListOfObservers (OCResourceHandle handle,
OCObservationId *obsIdList,
uint8_t numberOfIds,
- const char *notificationJSONPayload,
+ const OCRepPayload *payload,
OCQualityOfService qos);
* 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
/**
#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
//-----------------------------------------------------------------------------
/**
* 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"
} 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.
* @brief The @ref OCEntityHandler callback API must be implemented in the application in order
// 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;
/**
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.
// 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];
#include "logger.h"
#include "ocstack.h"
+#include "ocpayload.h"
#include <string.h>
#ifdef ARDUINOWIFI
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
{
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))
{
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)
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);
#include "ocstack.h"
#include "logger.h"
#include "occlient.h"
+#include "ocpayload.h"
// Tracking user input
static int UNICAST_DISCOVERY = 0;
//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";
}
}
+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>");
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)
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
{
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
{
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
{
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)
{
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.
{
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)
{
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);
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
{
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
{
#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"
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.
}
}
+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>");
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)
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
{
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
{
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 )
{
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);
}
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)
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.
#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
{"?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.
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>");
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;
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)
{
}
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)
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);
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)
{
return 0;
}
-std::string getQueryStrForGetPut(const char * responsePayload)
+std::string getQueryStrForGetPut()
{
-
- std::string jsonPayload(responsePayload);
-
return "/a/room";
}
#include "ocstack.h"
#include "logger.h"
#include "occlientslow.h"
+#include "ocpayload.h"
// Tracking user input
static int UNICAST_DISCOVERY = 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)
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,
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)
{
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)
{
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);
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;
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;
TEST_DISCOVER_REQ = 1,
TEST_NON_CON_OP,
TEST_CON_OP,
+ TEST_NON_CON_PUT,
+ TEST_CON_PUT,
MAX_TESTS
} CLIENT_TEST;
* POST & Discovery operations
*/
int InitGetRequest(OCQualityOfService qos);
+int InitPutRequest(OCQualityOfService qos);
int InitDiscovery();
/* Function to retrieve ip address, port no. of the server
#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'"
#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";
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)
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);
}
/*
}
OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
- char *payload, uint16_t maxPayloadSize)
+ OCRepPayload **payload)
{
OCEntityHandlerResult ehResult;
bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
// 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
{
}
OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
- char *payload, uint16_t maxPayloadSize)
+ OCRepPayload** payload)
{
OCEntityHandlerResult ehResult;
- char *putResp = constructJsonResponse(ehRequest);
+ OCRepPayload *putResp = constructResponse(ehRequest);
if(!putResp)
{
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.
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]))
{
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
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)
{
* 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.
{
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++)
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;
}
}
//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;
}
OCEntityHandlerResult ehResult = OC_EH_OK;
OCEntityHandlerResponse response;
- char payload[MAX_RESPONSE_LENGTH] = {0};
// Validate pointer
if (!entityHandlerRequest)
memset(response.sendVendorSpecificHeaderOptions, 0,
sizeof response.sendVendorSpecificHeaderOptions);
memset(response.resourceUri, 0, sizeof response.resourceUri);
+ OCRepPayload* payload = nullptr;
if (flag & OC_REQUEST_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
{
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;
OCEntityHandlerResult ehResult = OC_EH_OK;
OCEntityHandlerResponse response;
- char payload[MAX_RESPONSE_LENGTH] = {0};
// Validate pointer
if (!entityHandlerRequest)
memset(response.sendVendorSpecificHeaderOptions,
0, sizeof response.sendVendorSpecificHeaderOptions);
memset(response.resourceUri, 0, sizeof response.resourceUri);
+ OCRepPayload* payload = nullptr;
if (flag & OC_REQUEST_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
{
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;
}
}
+ OCPayloadDestroy(response.payload);
return ehResult;
}
}
}
- 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)
{
*/
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.
/* 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);
#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
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)
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;
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
{
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.
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))
{
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
{
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;
}
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)
{
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
{
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));
}
}
}
+
+ OCPayloadDestroy(response.payload);
return ehResult;
}
*/
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);
#include <pthread.h>
#include <ocstack.h>
#include <logger.h>
+#include "ocpayload.h"
const char *getResult(OCStackResult result);
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
{
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)
{
{
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 );
{
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)
{
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);
{
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)
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);
{
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 );
{
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
{
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);
{
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 );
{
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
{
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);
return 0;
}
+
void createResources()
{
light.state = false;
#include "logger.h"
#include "cJSON.h"
#include "ocserverslow.h"
+#include "ocpayload.h"
volatile sig_atomic_t gQuitFlag = 0;
//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)
{
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);
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");
}
{
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");
{
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)
{
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
{
}
// 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
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);
OC_LOG(ERROR, TAG, "OCStack process error");
return 0;
}
-
sleep(2);
}
for (auto iter = gRequestList.begin(); iter != gRequestList.end(); ++iter)
{
OICFree((*iter)->query);
- OICFree((*iter)->reqJSONPayload);
+ OCPayloadDestroy((*iter)->payload);
OICFree(*iter);
}
gRequestList.clear();
######################################################################
# Source files and Targets
######################################################################
+
ocserverbasicops = samples_env.Program('ocserverbasicops', ['common.cpp', 'ocserverbasicops.cpp'])
occlientbasicops = samples_env.Program('occlientbasicops', ['common.cpp', 'occlientbasicops.cpp'])
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'))
#include "ocstack.h"
#include "logger.h"
#include "occlientbasicops.h"
-#include "cJSON.h"
+#include "ocpayload.h"
#include "common.h"
#define TAG "occlientbasicops"
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;
}
}
+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>");
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)
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;
}
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;
}
{
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;
}
{
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;
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();
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;
}
#include <pthread.h>
#include "ocstack.h"
#include "logger.h"
-#include "cJSON.h"
+#include "ocpayload.h"
#include "ocserverbasicops.h"
#include "common.h"
//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
{
}
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
{
}
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.
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))
{
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
{
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;
}
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)
{
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
{
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));
}
}
}
+
+ OCPayloadDestroy(response.payload);
return ehResult;
}
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
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)
#include "cJSON.h"
#include "oic_malloc.h"
#include "oic_string.h"
+#include "ocpayload.h"
/// Module Name
#include <stdio.h>
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)
{
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;
}
{
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)
{
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);
}
{
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);
}
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);
}
#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.
{
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);
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"));
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;
resourceObserver->resUri);
result = OCDoResponse(&ehResponse);
}
+
+ OCPresencePayloadDestroy(presenceResBuf);
}
}
#endif
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;
}
{
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;
--- /dev/null
+//******************************************************************
+//
+// 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);
+}
--- /dev/null
+//******************************************************************
+//
+// 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;
+ err = err || cbor_encoder_create_map(&map, &propMap, 2);
+
+ CborEncoder curArray;
+ if(payload->types)
+ {
+ err = err || cbor_encode_text_string(&propMap,
+ OC_RSRVD_RESOURCE_TYPE,
+ sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
+ err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength);
+ OCStringLL* val = payload->types;
+ while(val)
+ {
+ err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value));
+ val = val->next;
+ }
+ err = err || cbor_encoder_close_container(&propMap, &curArray);
+ }
+ if(payload->interfaces)
+ {
+ err = err || cbor_encode_text_string(&propMap,
+ OC_RSRVD_INTERFACE,
+ sizeof(OC_RSRVD_INTERFACE) - 1);
+ err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength);
+ OCStringLL* val = payload->interfaces;
+ while(val)
+ {
+ err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value));
+ val = val->next;
+ }
+ err = err || cbor_encoder_close_container(&propMap, &curArray);
+ }
+ err = err || cbor_encoder_close_container(&map, &propMap);
+ }
+
+ // 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);
+ OCRepPayloadValue* value = payload->values;
+ while(value)
+ {
+ err = err || cbor_encode_text_string(&repMap,
+ value->name,
+ strlen(value->name));
+ switch(value->type)
+ {
+ case OCREP_PROP_NULL:
+ err = err || cbor_encode_null(&repMap);
+ break;
+ case OCREP_PROP_INT:
+ err = err || cbor_encode_int(&repMap,
+ value->i);
+ break;
+ case OCREP_PROP_DOUBLE:
+ err = err || cbor_encode_double(&repMap,
+ value->d);
+ break;
+ case OCREP_PROP_BOOL:
+ err = err || cbor_encode_boolean(&repMap,
+ value->b);
+ break;
+ case OCREP_PROP_STRING:
+ err = err || cbor_encode_text_string(&repMap,
+ value->str, strlen(value->str));
+ break;
+ case OCREP_PROP_OBJECT:
+ err = err || OCConvertSingleRepPayload(&repMap, value->obj);
+ break;
+ case OCREP_PROP_ARRAY:
+ err = err || OCConvertArray(&repMap, &value->arr);
+ break;
+ default:
+ OC_LOG_V(ERROR, TAG, "Invalid Prop type: %d",
+ value->type);
+ break;
+ }
+ value = value->next;
+ }
+
+ err = err || cbor_encoder_close_container(&map, &repMap);
+ }
+
+ // Close Map
+ err = err || cbor_encoder_close_container(parent, &map);
+
+ return err;
+}
+
+static OCStackResult OCConvertRepPayload(OCRepPayload* 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, CborIndefiniteLength);
+ err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_REPRESENTATION);
+
+ while(payload != NULL && !err)
+ {
+ err = err || OCConvertSingleRepPayload(&rootArray, payload);
+ payload = payload->next;
+ }
+
+ // Close main array
+ err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+ if(err)
+ {
+ OC_LOG_V(ERROR, TAG, "Convert Rep 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 OCConvertPresencePayload(OCPresencePayload* 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_PRESENCE);
+
+
+ CborEncoder map;
+ err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
+
+ // Sequence Number
+ err = err || cbor_encode_text_string(&map,
+ OC_RSRVD_NONCE,
+ sizeof(OC_RSRVD_NONCE) - 1);
+ err = err || cbor_encode_uint(&map, payload->sequenceNumber);
+
+ // Max Age
+ err = err || cbor_encode_text_string(&map,
+ OC_RSRVD_TTL,
+ sizeof(OC_RSRVD_TTL) - 1);
+ err = err || cbor_encode_uint(&map, payload->maxAge);
+
+ // Trigger
+ const char* triggerStr = convertTriggerEnumToString(payload->trigger);
+ err = err || AddTextStringToMap(&map, OC_RSRVD_TRIGGER, sizeof(OC_RSRVD_TRIGGER) - 1,
+ triggerStr);
+
+ // Resource type name
+ if(payload->trigger != OC_PRESENCE_TRIGGER_DELETE)
+ {
+ err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_RESOURCE_TYPE,
+ sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->resourceType);
+ }
+
+ // Close Map
+ err = err || cbor_encoder_close_container(&rootArray, &map);
+ err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+ if(err)
+ {
+ OC_LOG_V(ERROR, TAG, "Convert Presence 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;
+}
+
+bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+ const char* value)
+{
+ return cbor_encode_text_string(map, key, keylen) ||
+ cbor_encode_text_string(map, value, strlen(value));
+}
+
+bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+ const char* value)
+{
+ return value ? AddTextStringToMap(map, key, keylen, value) : false;
+}
--- /dev/null
+//******************************************************************
+//
+// 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 "logger.h"
+#include "oic_malloc.h"
+#include "ocstackinternal.h"
+#include "ocpayload.h"
+#include "cbor.h"
+
+#define TAG PCF("OCPayloadParse")
+
+static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal);
+static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal);
+static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal);
+static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent);
+static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal);
+static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal);
+static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal);
+
+OCStackResult OCParsePayload(OCPayload** outPayload, const uint8_t* payload, size_t payloadSize)
+{
+ CborParser parser;
+ CborValue rootValue;
+ bool err = false;
+
+ OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize, payload);
+ if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
+ {
+ OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
+ return OC_STACK_ERROR;
+ }
+
+ if(!cbor_value_is_array(&rootValue))
+ {
+ OC_LOG_V(ERROR, TAG, "CBOR payload root object is not an array :%x", rootValue.type);
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+
+ CborValue arrayValue;
+ // enter the array
+ err = err || cbor_value_enter_container(&rootValue, &arrayValue);
+
+ int payloadType;
+ err = err || cbor_value_get_int(&arrayValue, &payloadType);
+ err = err || cbor_value_advance_fixed(&arrayValue);
+
+ if(err)
+ {
+ OC_LOG_V(ERROR, TAG, "CBOR payload parse failed :%d", err);
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+
+ OCStackResult result = OC_STACK_ERROR;
+ switch(payloadType)
+ {
+ case PAYLOAD_TYPE_DISCOVERY:
+ result = OCParseDiscoveryPayload(outPayload, &arrayValue);
+ break;
+ case PAYLOAD_TYPE_DEVICE:
+ result = OCParseDevicePayload(outPayload, &arrayValue);
+ break;
+ case PAYLOAD_TYPE_PLATFORM:
+ result = OCParsePlatformPayload(outPayload, &arrayValue);
+ break;
+ case PAYLOAD_TYPE_REPRESENTATION:
+ result = OCParseRepPayload(outPayload, &arrayValue);
+ break;
+ case PAYLOAD_TYPE_PRESENCE:
+ result = OCParsePresencePayload(outPayload, &arrayValue);
+ break;
+ case PAYLOAD_TYPE_SECURITY:
+ result = OCParseSecurityPayload(outPayload, &arrayValue);
+ break;
+ default:
+ OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
+ result = OC_STACK_ERROR;
+ break;
+ }
+
+ if(result == OC_STACK_OK)
+ {
+ err = err || cbor_value_leave_container(&rootValue, &arrayValue);
+ if(err != CborNoError)
+ {
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+ }
+ else
+ {
+ OC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
+ }
+
+ return result;
+}
+
+void OCFreeOCStringLL(OCStringLL* ll);
+
+static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+ bool err = false;
+ char * securityData = NULL;
+
+ if(cbor_value_is_map(arrayVal))
+ {
+ CborValue curVal;
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
+
+ if(cbor_value_is_valid(&curVal))
+ {
+ size_t len;
+ err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL);
+ }
+ }
+ else
+ {
+ OC_LOG_V(ERROR, TAG, PCF("Cbor main value not a map"));
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+
+ err = err || cbor_value_advance(arrayVal);
+
+ if(err)
+ {
+ OC_LOG_V(ERROR, TAG, "Cbor in error condition");
+ OICFree(securityData);
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+
+ *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
+ OICFree(securityData);
+
+ return OC_STACK_OK;
+
+}
+
+static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+ bool err = false;
+
+ OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
+
+ if(!out)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+
+ size_t resourceCount = 0;
+ while(!err &&
+ cbor_value_is_map(arrayVal))
+ {
+ OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
+ if(!resource)
+ {
+ OC_LOG_V(ERROR, TAG, "Memory allocation failed");
+ return OC_STACK_NO_MEMORY;
+ }
+ CborValue curVal;
+
+ // Uri
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
+ size_t len;
+ err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
+
+ // SID
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
+ err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
+
+ // Prop Tag
+ {
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
+ // ResourceTypes
+ CborValue rtArray;
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtArray);
+
+ CborValue rtVal;
+ err = err || cbor_value_enter_container(&rtArray, &rtVal);
+
+ OCStringLL* llPtr = NULL;
+ while(!err && cbor_value_is_text_string(&rtVal))
+ {
+ if(resource->types == NULL)
+ {
+ resource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+ llPtr = resource->types;
+ if(!llPtr)
+ {
+ OC_LOG_V(ERROR, TAG, "Memory allocation failed");
+ OICFree(resource->uri);
+ OICFree(resource->sid);
+ OICFree(resource);
+ return OC_STACK_NO_MEMORY;
+ }
+ }
+ else
+ {
+ llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+ llPtr = llPtr->next;
+ if(!llPtr)
+ {
+ OC_LOG_V(ERROR, TAG, "Memory allocation failed");
+ OICFree(resource->uri);
+ OICFree(resource->sid);
+ OCFreeOCStringLL(resource->types);
+ OICFree(resource);
+ return OC_STACK_NO_MEMORY;
+ }
+
+ }
+
+ err = err || cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
+ err = err || cbor_value_advance(&rtVal);
+ }
+
+ err = err || cbor_value_leave_container(&rtArray, &rtVal);
+ //
+ // Interface Types
+ CborValue ifArray;
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifArray);
+ CborValue ifVal;
+ err = err || cbor_value_enter_container(&ifArray, &ifVal);
+
+ llPtr = NULL;
+ while(!err && cbor_value_is_text_string(&ifVal))
+ {
+ if(resource->interfaces == NULL)
+ {
+ resource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+ llPtr = resource->interfaces;
+ if(!llPtr)
+ {
+ OC_LOG_V(ERROR, TAG, "Memory allocation failed");
+ OICFree(resource->uri);
+ OICFree(resource->sid);
+ OCFreeOCStringLL(resource->types);
+ OICFree(resource);
+ return OC_STACK_NO_MEMORY;
+ }
+ }
+ else
+ {
+ llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+ llPtr = llPtr->next;
+ if(!llPtr)
+ {
+ OC_LOG_V(ERROR, TAG, "Memory allocation failed");
+ OICFree(resource->uri);
+ OICFree(resource->sid);
+ OCFreeOCStringLL(resource->types);
+ OCFreeOCStringLL(resource->interfaces);
+ OICFree(resource);
+ return OC_STACK_NO_MEMORY;
+ }
+ }
+
+ err = err || cbor_value_dup_text_string(&ifVal, &(llPtr->value), &len, NULL);
+ err = err || cbor_value_advance(&ifVal);
+ }
+ err = err || cbor_value_leave_container(&ifArray, &ifVal);
+
+ // Policy
+ {
+ CborValue policyMap;
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
+
+ // Bitmap
+ CborValue val;
+ err= err | cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
+ uint64_t temp = 0;
+ err = err || cbor_value_get_uint64(&val, &temp);
+ resource->bitmap = (uint8_t)temp;
+ // Secure Flag
+ err= err | cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
+ if(cbor_value_is_valid(&val))
+ {
+ err = err || cbor_value_get_boolean(&val, &(resource->secure));
+ // Port
+ err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
+ if(cbor_value_is_valid(&val) && cbor_value_is_map(&val))
+ {
+ CborValue port;
+ cbor_value_map_find_value(&val, OC_RSRVD_HOSTING_PORT, &port);
+ if(cbor_value_is_valid(&port))
+ {
+ err = err || cbor_value_get_uint64(&val, &temp);
+ resource->port = (uint16_t)temp;
+ }
+ }
+ }
+ }
+ }
+
+ err = err || cbor_value_advance(arrayVal);
+ if(err)
+ {
+ OICFree(resource->uri);
+ OICFree(resource->sid);
+ OCFreeOCStringLL(resource->types);
+ OCFreeOCStringLL(resource->interfaces);
+ OICFree(resource);
+ OCDiscoveryPayloadDestroy(out);
+ OC_LOG_V(ERROR, TAG, "CBOR in error condition", err);
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+ ++resourceCount;
+ OCDiscoveryPayloadAddNewResource(out, resource);
+ }
+
+ *outPayload = (OCPayload*)out;
+
+ return OC_STACK_OK;
+}
+
+static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+ bool err = false;
+
+ if(cbor_value_is_map(arrayVal))
+ {
+ char* uri = NULL;
+ uint8_t* sid = NULL;
+ char* dname = NULL;
+ char* specVer = NULL;
+ char* dmVer = NULL;
+ CborValue curVal;
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
+ size_t len;
+ err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
+
+ // Representation
+ {
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
+
+ CborValue repVal;
+ // Device ID
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_ID, &repVal);
+ err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
+ // Device Name
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
+ err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
+ // Device Spec Version
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
+ err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
+ // Data Model Version
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
+ err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
+
+ }
+
+ err = err || cbor_value_advance(arrayVal);
+
+ if(err)
+ {
+ OICFree(uri);
+ OICFree(sid);
+ OICFree(dname);
+ OICFree(specVer);
+ OICFree(dmVer);
+ OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+
+ *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
+
+ OICFree(uri);
+ OICFree(sid);
+ OICFree(dname);
+ OICFree(specVer);
+ OICFree(dmVer);
+ if(!*outPayload)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+
+ return OC_STACK_OK;
+ }
+ else
+ {
+ OC_LOG(ERROR, TAG, PCF("Root device node was not a map"));
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+
+}
+
+static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+ bool err = false;
+
+ if(cbor_value_is_map(arrayVal))
+ {
+ char* uri = NULL;
+ OCPlatformInfo info = {};
+ CborValue curVal;
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
+ size_t len;
+ err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
+
+ // Representation
+ {
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
+
+ CborValue repVal;
+ // Platform ID
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
+ err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
+
+ // MFG Name
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
+ err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
+
+ // MFG URL
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
+ }
+
+ // Model Num
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
+ }
+
+ // Date of Mfg
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
+ NULL);
+ }
+
+ // Platform Version
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
+ NULL);
+ }
+
+ // OS Version
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
+ &len, NULL);
+ }
+
+ // Hardware Version
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
+ NULL);
+ }
+
+ // Firmware Version
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
+ NULL);
+ }
+
+ // Support URL
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
+ }
+
+ // System Time
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
+ }
+ }
+
+ err = err || cbor_value_advance(arrayVal);
+
+ if(err)
+ {
+ OICFree(info.dateOfManufacture);
+ OICFree(info.firmwareVersion);
+ OICFree(info.hardwareVersion);
+ OICFree(info.manufacturerName);
+ OICFree(info.manufacturerUrl);
+ OICFree(info.modelNumber);
+ OICFree(info.operatingSystemVersion);
+ OICFree(info.platformID);
+ OICFree(info.platformVersion);
+ OICFree(info.supportUrl);
+ OICFree(info.systemTime);
+ OC_LOG(ERROR, TAG, PCF("CBOR error In ParsePlatformPayload"));
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+
+ *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
+
+ if(!*outPayload)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+
+ return OC_STACK_OK;
+ }
+ else
+ {
+ OC_LOG(ERROR, TAG, PCF("Root device node was not a map"));
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+}
+
+static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
+{
+ CborValue insideArray;
+ bool err = false;
+ uint64_t tempInt = 0;
+ OCRepPayloadPropType type;
+ size_t dimensions[MAX_REP_ARRAY_DEPTH];
+ err = err || cbor_value_enter_container(container, &insideArray);
+
+ err = err || cbor_value_get_uint64(&insideArray, &tempInt);
+ err = err || cbor_value_advance_fixed(&insideArray);
+ type = (OCRepPayloadPropType)tempInt;
+
+ for(int i = 0; i < MAX_REP_ARRAY_DEPTH; ++ i)
+ {
+ err = err || cbor_value_get_uint64(&insideArray, &tempInt);
+ err = err || cbor_value_advance_fixed(&insideArray);
+ dimensions[i] = tempInt;
+ }
+
+ size_t dimTotal = calcDimTotal(dimensions);
+
+ void* arr = NULL;
+ char* tempStr;
+ size_t len;
+ OCRepPayload* pl;
+ switch(type)
+ {
+ case OCREP_PROP_INT:
+ arr = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
+ for(size_t i = 0; i < dimTotal && !err; ++i)
+ {
+ err = err || cbor_value_get_int64(&insideArray, &(((int64_t*)arr)[i]));
+ err = err || cbor_value_advance_fixed(&insideArray);
+ }
+ if(!err &&
+ OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
+ {}
+ else
+ {
+ err = CborUnknownError;
+ }
+ break;
+ case OCREP_PROP_DOUBLE:
+ arr = (double*)OICMalloc(dimTotal * sizeof(double));
+ for(size_t i = 0; i < dimTotal && !err; ++i)
+ {
+ err = err || cbor_value_get_double(&insideArray, &(((double*)arr)[i]));
+ err = err || cbor_value_advance_fixed(&insideArray);
+ }
+ if(!err &&
+ OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
+ {}
+ else
+ {
+ err = CborUnknownError;
+ }
+ break;
+ case OCREP_PROP_BOOL:
+ arr = (bool*)OICMalloc(dimTotal * sizeof(bool));
+ for(size_t i = 0; i < dimTotal && !err; ++i)
+ {
+ err = err || cbor_value_get_boolean(&insideArray, &(((bool*)arr)[i]));
+ err = err || cbor_value_advance_fixed(&insideArray);
+ }
+ if(!err &&
+ OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
+ {}
+ else
+ {
+ err = CborUnknownError;
+ }
+ break;
+ case OCREP_PROP_STRING:
+ arr = (char**)OICMalloc(dimTotal * sizeof(char*));
+ for(size_t i = 0; i < dimTotal && !err; ++i)
+ {
+ err = err || cbor_value_dup_text_string(&insideArray, &tempStr,
+ &len, NULL);
+ ((char**)arr)[i] = tempStr;
+ }
+ if(!err &&
+ OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
+ {}
+ else
+ {
+ err = CborUnknownError;
+ }
+ break;
+ case OCREP_PROP_OBJECT:
+ arr = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+ for(size_t i = 0; i < dimTotal && !err; ++i)
+ {
+ pl = NULL;
+ err = err || OCParseSingleRepPayload(&pl, &insideArray);
+ ((OCRepPayload**)arr)[i] = pl;
+ err = err || cbor_value_advance(&insideArray);
+ }
+ if(!err &&
+ OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
+ {}
+ else
+ {
+ err = CborUnknownError;
+ }
+ break;
+ default:
+ OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
+ err = CborUnknownError;
+ break;
+ }
+
+ return err;
+}
+
+static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
+{
+ *outPayload = OCRepPayloadCreate();
+ OCRepPayload* curPayload = *outPayload;
+ bool err = false;
+ if(!*outPayload)
+ {
+ return CborErrorOutOfMemory;
+ }
+
+ size_t len;
+ CborValue curVal;
+ err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
+ if(cbor_value_is_valid(&curVal))
+ {
+ err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
+ NULL);
+ }
+
+ err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
+ if(cbor_value_is_valid(&curVal))
+ {
+ CborValue insidePropArray;
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
+ &insidePropArray);
+
+ if(cbor_value_is_array(&insidePropArray))
+ {
+ CborValue rtArray;
+ err = err || cbor_value_enter_container(&insidePropArray, &rtArray);
+
+ while(!err && cbor_value_is_valid(&rtArray))
+ {
+ char* curRt;
+ cbor_value_dup_text_string(&rtArray, &curRt, &len, NULL);
+ OCRepPayloadAddResourceTypeAsOwner(curPayload, curRt);
+ }
+
+ err = err || cbor_value_leave_container(&insidePropArray, &rtArray);
+ }
+
+ err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropArray);
+
+ if(cbor_value_is_array(&insidePropArray))
+ {
+ CborValue ifArray;
+ err = err || cbor_value_enter_container(&insidePropArray, &ifArray);
+
+ while(!err && cbor_value_is_valid(&ifArray))
+ {
+ char* curIf;
+ err = err || cbor_value_dup_text_string(&ifArray, &curIf, &len, NULL);
+ OCRepPayloadAddInterfaceAsOwner(curPayload, curIf);
+ }
+
+ err = err || cbor_value_leave_container(&insidePropArray, &ifArray);
+ }
+ }
+ err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
+ if(cbor_value_is_map(&curVal))
+ {
+ CborValue repMap;
+ err = err || cbor_value_enter_container(&curVal, &repMap);
+
+ while(!err && cbor_value_is_valid(&repMap))
+ {
+ char* name;
+ err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
+
+ err = err || cbor_value_advance(&repMap);
+
+ int64_t intval = 0;
+ bool boolval = false;
+ char* strval = NULL;
+ double doubleval = 0;
+ OCRepPayload* pl;
+
+ switch(cbor_value_get_type(&repMap))
+ {
+ case CborNullType:
+ OCRepPayloadSetNull(curPayload, name);
+ break;
+ case CborIntegerType:
+ err = err || cbor_value_get_int64(&repMap, &intval);
+ OCRepPayloadSetPropInt(curPayload, name, intval);
+ break;
+ case CborDoubleType:
+ err = err || cbor_value_get_double(&repMap, &doubleval);
+ OCRepPayloadSetPropDouble(curPayload, name, doubleval);
+ case CborBooleanType:
+ err = err || cbor_value_get_boolean(&repMap, &boolval);
+ OCRepPayloadSetPropBool(curPayload, name, boolval);
+ break;
+ case CborTextStringType:
+ err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
+ OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
+ break;
+ case CborMapType:
+ err = err || OCParseSingleRepPayload(&pl, &repMap);
+ OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
+ break;
+ case CborArrayType:
+ err = err || OCParseArray(curPayload, name, &repMap);
+ break;
+ default:
+ OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
+ err = true;
+ }
+
+ err = err || cbor_value_advance(&repMap);
+ OICFree(name);
+ }
+ err = err || cbor_value_leave_container(&curVal, &repMap);
+ }
+
+ if(err)
+ {
+ OCRepPayloadDestroy(*outPayload);
+ }
+
+ return err;
+}
+static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+ bool err = false;
+
+ OCRepPayload* rootPayload = NULL;
+ OCRepPayload* curPayload = NULL;
+ OCRepPayload* temp = NULL;
+ while(!err && cbor_value_is_map(arrayVal))
+ {
+ err = err || OCParseSingleRepPayload(&temp, arrayVal);
+
+ if(rootPayload == NULL)
+ {
+ rootPayload = temp;
+ curPayload = temp;
+ }
+ else
+ {
+ curPayload->next = temp;
+ curPayload = curPayload->next;
+ }
+
+
+ err = err || cbor_value_advance(arrayVal);
+ if(err)
+ {
+ OCRepPayloadDestroy(rootPayload);
+ OC_LOG_V(ERROR, TAG, PCF("CBOR error in ParseRepPayload"));
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+ }
+
+ *outPayload = (OCPayload*)rootPayload;
+
+ return OC_STACK_OK;
+}
+
+static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+ bool err = false;
+ if(cbor_value_is_map(arrayVal))
+ {
+ uint64_t seqNum = 0;
+ uint64_t maxAge = 0;
+ OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
+ char* tempStr = NULL;
+ size_t len = 0;
+
+ CborValue curVal;
+ // Sequence Number
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
+ err = err || cbor_value_get_uint64(&curVal, &seqNum);
+
+ // Max Age
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
+ err = err || cbor_value_get_uint64(&curVal, &maxAge);
+
+ // Trigger
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
+ err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
+ trigger = convertTriggerStringToEnum(tempStr);
+ OICFree(tempStr);
+ tempStr = NULL;
+
+ // Resource type name
+ err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
+ if(cbor_value_is_valid(&curVal))
+ {
+ err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
+ }
+
+ err = err || cbor_value_advance(arrayVal);
+
+ if(!err)
+ {
+ *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
+ }
+ OICFree(tempStr);
+
+ if(err)
+ {
+ OCPayloadDestroy(*outPayload);
+ OC_LOG_V(ERROR, TAG, PCF("CBOR error Parse Presence Payload"));
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+
+ if(!*outPayload)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+
+ return OC_STACK_OK;
+ }
+ else
+ {
+ OC_LOG(ERROR, TAG, PCF("Root presence node was not a map"));
+ return OC_STACK_MALFORMED_RESPONSE;
+ }
+}
#include "oic_string.h"
#include "logger.h"
#include "cJSON.h"
+#include "ocpayload.h"
#include "cacommon.h"
#include "cainterface.h"
}
/*
- * Encodes platform info into json and returns a string on the heap.
- * Caller responsible for freeing the string.
- */
-static char* GetJSONStringFromPlatformInfo(OCPlatformInfo info)
-{
- cJSON *rootObj = cJSON_CreateObject();
-
- if (!rootObj)
- {
- return NULL;
- }
-
- cJSON *repObj = NULL;
- char *jsonEncodedInfo = NULL;
-
- cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
- cJSON_CreateString(GetVirtualResourceUri(OC_PLATFORM_URI)));
-
- cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
-
- if (!repObj)
- {
- return NULL;
- }
- if (info.platformID)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_ID,
- cJSON_CreateString(info.platformID));
- }
-
- if (info.manufacturerName)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_NAME,
- cJSON_CreateString(info.manufacturerName));
- }
-
- if (info.manufacturerUrl)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_URL,
- cJSON_CreateString(info.manufacturerUrl));
- }
-
- if (info.modelNumber)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_MODEL_NUM,
- cJSON_CreateString(info.modelNumber));
- }
-
- if (info.dateOfManufacture)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_DATE,
- cJSON_CreateString(info.dateOfManufacture));
- }
-
- if (info.platformVersion)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_VERSION,
- cJSON_CreateString(info.platformVersion));
- }
-
- if (info.operatingSystemVersion)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_OS_VERSION,
- cJSON_CreateString(info.operatingSystemVersion));
- }
-
- if (info.hardwareVersion)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_HARDWARE_VERSION,
- cJSON_CreateString(info.hardwareVersion));
- }
-
- if (info.firmwareVersion)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_FIRMWARE_VERSION,
- cJSON_CreateString(info.firmwareVersion));
- }
-
- if (info.supportUrl)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_SUPPORT_URL,
- cJSON_CreateString(info.supportUrl));
- }
-
- if (info.systemTime)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_SYSTEM_TIME,
- cJSON_CreateString(info.systemTime));
- }
-
- jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
-
- cJSON_Delete(rootObj);
-
- return jsonEncodedInfo;
-}
-
-/*
- * Encodes device info into json and returns a string on the heap.
- * Caller responsible for freeing the string.
- */
-static char* GetJSONStringFromDeviceInfo(OCDeviceInfo info)
-{
- cJSON *rootObj = cJSON_CreateObject();
-
- if (!rootObj)
- {
- return NULL;
- }
-
- cJSON *repObj = NULL;
- char *jsonEncodedInfo = NULL;
-
- cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
- cJSON_CreateString(GetVirtualResourceUri(OC_DEVICE_URI)));
-
- cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
-
- if (!repObj)
- {
- return NULL;
- }
-
- cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_ID,
- cJSON_CreateString(OCGetServerInstanceIDString()));
-
- if (info.deviceName)
- {
- cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_NAME,
- cJSON_CreateString(info.deviceName));
- }
-
- cJSON_AddItemToObject (repObj, OC_RSRVD_SPEC_VERSION,
- cJSON_CreateString(OC_SPEC_VERSION));
-
- cJSON_AddItemToObject (repObj, OC_RSRVD_DATA_MODEL_VERSION,
- cJSON_CreateString(OC_DATA_MODEL_VERSION));
-
- jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
-
- cJSON_Delete(rootObj);
-
- return jsonEncodedInfo;
-}
-
-/*
* Function will extract 0, 1 or 2 filters from query.
* More than 2 filters or unsupported filters will result in error.
* If both filters are of the same supported type, the 2nd one will be picked.
return result;
}
-OCStackResult copyStringIfEnoughSpace(char* dest, const char *src, uint16_t *remaining)
+OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
+ OCDiscoveryPayload* payload, CATransportAdapter_t adapter )
{
- if (!dest || !src || !remaining)
+ if (!resourcePtr || !payload)
{
return OC_STACK_INVALID_PARAM;
}
-
- size_t srcLen = strlen(src);
-
- if (srcLen < *remaining)
- {
- OICStrcpy(dest, *remaining, src);
- *remaining = *remaining - srcLen;
- return OC_STACK_OK;
- }
- else
+ uint16_t port = 0;
+ if (resourcePtr->resourceProperties & OC_SECURE)
{
- return OC_STACK_ERROR;
+ if(GetSecurePortInfo (adapter, &port) != OC_STACK_OK)
+ {
+ port = 0;
+ }
}
-}
-
-OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr, char *out,
- uint16_t *remaining, CATransportAdapter_t adapter )
-{
- if(!resourcePtr || !out || !remaining)
- {
- return OC_STACK_INVALID_PARAM;
- }
-
- OCResourceType *resourceTypePtr = NULL;
- OCResourceInterface *interfacePtr = NULL;
- cJSON *resObj = NULL;
- cJSON *policyObj = NULL;
- cJSON *rtArray = NULL;
- char *jsonStr = NULL;
- OCStackResult ret = OC_STACK_OK;
-
- OC_LOG_V(INFO, TAG, PCF("Encoding resource %s"), resourcePtr->uri);
- resObj = cJSON_CreateObject();
-
- if (resourcePtr)
- {
- // URI
- cJSON_AddItemToObject (resObj, OC_RSRVD_HREF, cJSON_CreateString(resourcePtr->uri));
-
- // resource types
- cJSON_AddItemToObject (resObj, OC_RSRVD_RESOURCE_TYPE, rtArray = cJSON_CreateArray());
- resourceTypePtr = resourcePtr->rsrcType;
- while (resourceTypePtr)
- {
- cJSON_AddItemToArray (rtArray,
- cJSON_CreateString(resourceTypePtr->resourcetypename));
- resourceTypePtr = resourceTypePtr->next;
- }
- // interfaces
- cJSON_AddItemToObject (resObj, OC_RSRVD_INTERFACE, rtArray = cJSON_CreateArray());
- interfacePtr = resourcePtr->rsrcInterface;
- while (interfacePtr)
- {
- cJSON_AddItemToArray (rtArray, cJSON_CreateString(interfacePtr->name));
- interfacePtr = interfacePtr->next;
- }
-
- // Policy
- cJSON_AddItemToObject (resObj, OC_RSRVD_POLICY, policyObj = cJSON_CreateObject());
-
- if (policyObj)
- {
- cJSON_AddNumberToObject (policyObj, OC_RSRVD_BITMAP,
- resourcePtr->resourceProperties & (OC_OBSERVABLE|OC_DISCOVERABLE));
- // Set secure flag for secure resources
- if (resourcePtr->resourceProperties & OC_SECURE)
- {
- cJSON_AddNumberToObject(policyObj, OC_RSRVD_SECURE, OC_RESOURCE_SECURE);
- //Set the IP port also as secure resources are hosted on a different port
- uint16_t port = 0;
- if (GetSecurePortInfo(adapter, &port) == OC_STACK_OK)
- {
- cJSON_AddNumberToObject(policyObj, OC_RSRVD_HOSTING_PORT, port);
- }
- }
- }
- else
- {
- cJSON_Delete(resObj);
- return OC_STACK_NO_MEMORY;
- }
- }
- jsonStr = cJSON_PrintUnformatted (resObj);
-
- if(!jsonStr)
- {
- cJSON_Delete(resObj);
- return OC_STACK_NO_MEMORY;
- }
-
- ret = copyStringIfEnoughSpace(out, jsonStr, remaining);
-
- cJSON_Delete (resObj);
- OICFree (jsonStr);
-
- return ret;
-}
-
-OCStackResult BuildVirtualResourceResponseForDevice(char *out, uint16_t *remaining)
-{
- if(!out || !remaining)
- {
- return OC_STACK_INVALID_PARAM;
- }
-
- OCStackResult ret = OC_STACK_ERROR;
- char *jsonStr = NULL;
-
- jsonStr = GetJSONStringFromDeviceInfo(savedDeviceInfo);
-
- if(jsonStr)
- {
- ret = copyStringIfEnoughSpace(out, jsonStr, remaining);
- OICFree(jsonStr);
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("Error encoding save device info."));
- ret = OC_STACK_ERROR;
- }
- return ret;
-}
-
-OCStackResult BuildVirtualResourceResponseForPlatform(char *out, uint16_t *remaining)
-{
- if(!out || !remaining)
- {
- return OC_STACK_INVALID_PARAM;
- }
-
- OCStackResult ret = OC_STACK_ERROR;
- char *jsonStr = NULL;
-
- jsonStr = GetJSONStringFromPlatformInfo(savedPlatformInfo);
-
- if(jsonStr)
- {
- ret = copyStringIfEnoughSpace(out, jsonStr, remaining);
- OICFree(jsonStr);
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("Error encoding save platform info."));
- ret = OC_STACK_ERROR;
- }
-
- return ret;
+ OCDiscoveryPayloadAddResource(payload, resourcePtr, port);
+ return OC_STACK_OK;
}
-
const char * GetVirtualResourceUri( OCVirtualResources resource)
{
if (resource < OC_MAX_VIRTUAL_RESOURCES)
}
OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCResource *resource,
- char *discoveryPayload)
+ OCPayload *discoveryPayload)
{
OCEntityHandlerResponse response = {};
response.ehResult = OC_EH_OK;
response.payload = discoveryPayload;
- response.payloadSize = strlen((const char *)discoveryPayload) + 1;
response.persistentBufferFlag = 0;
response.requestHandle = (OCRequestHandle) request;
response.resourceHandle = (OCResourceHandle) resource;
return OCDoResponse(&response);
}
-static OCStackResult appendDeviceIDAndOpenLinksArray (char *out, uint16_t *remaining)
-{
- if (!out || !remaining)
- {
- return OC_STACK_INVALID_PARAM;
- }
-
- const char *deviceID = OCGetServerInstanceIDString();
-
- char deviceIDJSONField[MAX_RESPONSE_LENGTH] = {};
-
- // Format is : {"di":"UUID","links":[
- sprintf (deviceIDJSONField, "{\"%s\":\"%s\"%s\"%s\":[", OC_RSRVD_DEVICE_ID, deviceID,
- OC_JSON_SEPARATOR_STR, OC_RSRVD_LINKS);
-
- uint16_t lenDeviceIDJSON = strlen(deviceIDJSONField);
-
- if (lenDeviceIDJSON > *remaining)
- {
- return OC_STACK_ERROR;
- }
- else
- {
- OICStrcat(out, *remaining, deviceIDJSONField);
- *remaining -= lenDeviceIDJSON;
- }
-
- return OC_STACK_OK;
-}
-
static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
{
if (!request || !resource)
}
OCStackResult discoveryResult = OC_STACK_ERROR;
+ OCPayload* payload = NULL;
char *filterOne = NULL;
char *filterTwo = NULL;
- uint16_t remaining = 0;
-
- char discoveryBuffer[MAX_RESPONSE_LENGTH] = {};
OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
- remaining = MAX_RESPONSE_LENGTH - sizeof ('\0');
if (virtualUriInRequest == OC_WELL_KNOWN_URI)
{
discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
- &filterOne, &filterTwo);
+ &filterOne, &filterTwo);
if (discoveryResult != OC_STACK_OK)
{
OC_LOG_V(ERROR, TAG, "Error (%d) validating query.\n", discoveryResult);
return discoveryResult;
}
- char *ptrIntoBuffer = discoveryBuffer;
+ payload = (OCPayload*)OCDiscoveryPayloadCreate();
- discoveryResult = appendDeviceIDAndOpenLinksArray(ptrIntoBuffer, &remaining);
-
- while(resource && discoveryResult == OC_STACK_OK)
+ if(!payload)
{
- if(includeThisResourceInResponse(resource, filterOne, filterTwo))
- {
- ptrIntoBuffer += strlen(ptrIntoBuffer);
-
- discoveryResult = BuildVirtualResourceResponse(resource, ptrIntoBuffer,
- &remaining, (CATransportAdapter_t)request->devAddr.adapter);
-
- if (discoveryResult != OC_STACK_OK)
- {
- OC_LOG_V(INFO, TAG, "Error (%d) encoding %s", discoveryResult, resource->uri);
- break;
- }
-
- ptrIntoBuffer += strlen(ptrIntoBuffer);
- if (remaining > sizeof(OC_JSON_SEPARATOR))
- {
- *ptrIntoBuffer = OC_JSON_SEPARATOR;
- ++ptrIntoBuffer;
- --remaining;
- }
- else
- {
- OC_LOG(INFO, TAG, PCF("Out of space in buffer"));
- break;
- }
-
- }
- resource = resource->next;
+ return OC_STACK_NO_MEMORY;
}
- size_t lenDiscoveryBuff = strlen (discoveryBuffer);
- // Traling separator replaced with closing of "links" array.
- // discoveryBuffer guaranteed to be null terminated as "remaining"
- // accounts for '\0' when initialized.
- if (lenDiscoveryBuff > 0 && discoveryBuffer[lenDiscoveryBuff - 1] == OC_JSON_SEPARATOR)
- {
- discoveryBuffer[lenDiscoveryBuff - 1] = ']';
- }
- else
+ for(;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
{
- // If No trailing separator then close links array anyway.
- discoveryBuffer[lenDiscoveryBuff] = ']';
- }
- --remaining;
- ptrIntoBuffer += strlen(ptrIntoBuffer);
-
- // Close array element brace.
- if (remaining > sizeof ('}'))
- {
- *ptrIntoBuffer = '}';
- --remaining;
- }
- else
- {
- discoveryResult = OC_STACK_ERROR;
+ if(includeThisResourceInResponse(resource, filterOne, filterTwo))
+ {
+ discoveryResult = BuildVirtualResourceResponse(resource,
+ (OCDiscoveryPayload*)payload,
+ (CATransportAdapter_t)request->devAddr.adapter);
+ }
}
}
-
else if (virtualUriInRequest == OC_DEVICE_URI)
{
- discoveryResult = BuildVirtualResourceResponseForDevice(discoveryBuffer, &remaining);
+ payload = (OCPayload*)OCDevicePayloadCreate(GetVirtualResourceUri(OC_DEVICE_URI),
+ OCGetServerInstanceID(), savedDeviceInfo.deviceName,
+ OC_SPEC_VERSION, OC_DATA_MODEL_VERSION);
+ if (!payload)
+ {
+ discoveryResult = OC_STACK_NO_MEMORY;
+ }
}
else if (virtualUriInRequest == OC_PLATFORM_URI)
{
- discoveryResult = BuildVirtualResourceResponseForPlatform(discoveryBuffer, &remaining);
+ OCPlatformPayload* payload = OCPlatformPayloadCreate(
+ GetVirtualResourceUri(OC_PLATFORM_URI),
+ &savedPlatformInfo);
+ if (!payload)
+ {
+ discoveryResult = OC_STACK_NO_MEMORY;
+ }
}
#ifdef WITH_PRESENCE
if(discoveryResult == OC_STACK_OK)
{
discoveryResult = SendNonPersistantDiscoveryResponse(request, resource,
- discoveryBuffer);
+ payload);
+ OCPayloadDestroy(payload);
}
else
{
OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
request->method, (OCResourceHandle) NULL, request->query,
- request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
+ request->payload, request->payloadSize,
+ request->numRcvdVendorSpecificHeaderOptions,
request->rcvdVendorSpecificHeaderOptions,
(OCObserveAction)request->observationOption, (OCObservationId)0);
VERIFY_SUCCESS(result, OC_STACK_OK);
result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
request->method, (OCResourceHandle) resource, request->query,
- request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
+ request->payload, request->payloadSize, request->numRcvdVendorSpecificHeaderOptions,
request->rcvdVendorSpecificHeaderOptions,
(OCObserveAction)request->observationOption, 0);
VERIFY_SUCCESS(result, OC_STACK_OK);
result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
request->method, (OCResourceHandle) resource, request->query,
- request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
+ request->payload, request->payloadSize, request->numRcvdVendorSpecificHeaderOptions,
request->rcvdVendorSpecificHeaderOptions,
(OCObserveAction)request->observationOption, (OCObservationId) 0);
if(result != OC_STACK_OK)
#include "ocresourcehandler.h"
#include "oic_malloc.h"
#include "oic_string.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
#include "cacommon.h"
#include "cainterface.h"
serverResponse = (OCServerResponse *) OICCalloc(1, sizeof(OCServerResponse));
VERIFY_NON_NULL(serverResponse);
- serverResponse->payload = (char *) OICCalloc(1, MAX_RESPONSE_LENGTH);
- VERIFY_NON_NULL(serverResponse->payload);
+ serverResponse->payload = NULL;
- serverResponse->remainingPayloadSize = MAX_RESPONSE_LENGTH;
serverResponse->requestHandle = requestHandle;
*response = serverResponse;
return NULL;
}
-/**
- * Add a server request to the server request list
- *
- * @param request - initialized server request that is created by this function
- * @param coapID - ID of CoAP pdu
- * @param delayedResNeeded - delayed response required 0=no 1=yes
- * @param secured - secure endpoint 0=no 1=yes
- * @param notificationFlag - //TODO: remove - does not appear to be used any longer
- * @param method - RESTful method
- * @param numRcvdVendorSpecificHeaderOptions - number of received vendor specific header options
- * @param observationOption - value of observation option
- * @param qos - request QOS
- * @param query - request query
- * @param rcvdVendorSpecificHeaderOptions - received vendor specific header options
- * @param reqJSONPayload - request JSON payload
- * @param requestToken - request token
- * @param tokenLength - request token length
- * @param resourceUrl - URL of resource
- * @param reqTotalSize - total size of the request
- * @param addressInfo - CA Address
- * @param connectivityType - connection type
- *
- * @return
- * OCStackResult
- */
OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
uint8_t delayedResNeeded, uint8_t notificationFlag, OCMethod method,
uint8_t numRcvdVendorSpecificHeaderOptions, uint32_t observationOption,
OCQualityOfService qos, char * query,
OCHeaderOption * rcvdVendorSpecificHeaderOptions,
- char * reqJSONPayload, CAToken_t requestToken, uint8_t tokenLength,
+ uint8_t * payload, CAToken_t requestToken, uint8_t tokenLength,
char * resourceUrl, size_t reqTotalSize, const OCDevAddr *devAddr)
{
OCServerRequest * serverRequest = NULL;
- //Note: OCServerRequest includes 1 byte for the JSON Payload. payloadSize is calculated
- //as the required length of the string, so this will result in enough room for the
- //null terminator as well.
serverRequest = (OCServerRequest *) OICCalloc(1, sizeof(OCServerRequest) +
(reqTotalSize ? reqTotalSize : 1) - 1);
VERIFY_NON_NULL(devAddr);
memcpy(serverRequest->rcvdVendorSpecificHeaderOptions, rcvdVendorSpecificHeaderOptions,
MAX_HEADER_OPTIONS * sizeof(OCHeaderOption));
}
- if(reqJSONPayload && reqTotalSize)
+ if(payload && reqTotalSize)
{
- OICStrcpy(serverRequest->reqJSONPayload, reqTotalSize, reqJSONPayload);
+ // destination is at least 1 greater than the source, so a NULL always exists in the
+ // last character
+ memcpy(serverRequest->payload, payload, reqTotalSize);
+ serverRequest->payloadSize = reqTotalSize;
}
+
serverRequest->requestComplete = 0;
if(requestToken)
{
return OC_STACK_NO_MEMORY;
}
-/**
- * Form the OCEntityHandlerRequest struct that is passed to a resource's entity handler
- *
- * @param entityHandlerRequest - pointer to the OCEntityHandlerRequest struct that is created.
- * Required to be zero-initialized before calling this function.
- * @param request - request handle
- * @param method - RESTful method
- * @param resource - resource handle
- * @param queryBuf - resource query of request
- * @param bufReqPayload - JSON payload of request
- * @param numVendorOptions - number of vendor options
- * @param vendorOptions - vendor options
- * @param observeAction - observe action flag
- * @param observeID - observe ID
- *
- * @return
- * OCStackResult
- */
OCStackResult FormOCEntityHandlerRequest(
OCEntityHandlerRequest * entityHandlerRequest,
OCRequestHandle request,
OCMethod method,
OCResourceHandle resource,
char * queryBuf,
- char * bufReqPayload,
+ uint8_t * payload,
+ size_t payloadSize,
uint8_t numVendorOptions,
OCHeaderOption * vendorOptions,
OCObserveAction observeAction,
entityHandlerRequest->query = queryBuf;
entityHandlerRequest->obsInfo.action = observeAction;
entityHandlerRequest->obsInfo.obsId = observeID;
+
+ if(payload && payloadSize)
+ {
+ if(OCParsePayload(&entityHandlerRequest->payload, payload, payloadSize) != OC_STACK_OK)
+ {
+ return OC_STACK_ERROR;
+ }
+ }
+ else
+ {
+ entityHandlerRequest->payload = NULL;
+ }
+
entityHandlerRequest->numRcvdVendorSpecificHeaderOptions = numVendorOptions;
entityHandlerRequest->rcvdVendorSpecificHeaderOptions = vendorOptions;
- entityHandlerRequest->reqJSONPayload = bufReqPayload;
return OC_STACK_OK;
}
return OC_STACK_ERROR;
}
- OC_LOG_V(INFO, TAG, "Inside HandleSingleResponse: %s", ehResponse->payload);
-
- if(ehResponse->payloadSize >= (MAX_RESPONSE_LENGTH))// - OC_JSON_PREFIX_LEN - OC_JSON_SUFFIX_LEN))
- {
- OC_LOG_V(ERROR, TAG, "Response payload size was too large. Max is %hu, payload size was %hu",
- (MAX_RESPONSE_LENGTH - OC_JSON_PREFIX_LEN - OC_JSON_SUFFIX_LEN), ehResponse->payloadSize);
- return OC_STACK_INVALID_PARAM;
- }
-
OCServerRequest *serverRequest = (OCServerRequest *)ehResponse->requestHandle;
CopyDevAddrToEndpoint(&serverRequest->devAddr, &responseEndpoint);
responseInfo.info.options = NULL;
}
- char payload[MAX_RESPONSE_LENGTH + OC_JSON_PREFIX_LEN + OC_JSON_SUFFIX_LEN + 1] = {};
-
// Put the JSON prefix and suffix around the payload
- OICStrcpy(payload, sizeof(payload), OC_JSON_PREFIX);
- if(ehResponse->payloadSize)
+ if(ehResponse->payload)
{
- OICStrcatPartial(payload, sizeof(payload),
- ehResponse->payload,
- ehResponse->payloadSize < MAX_RESPONSE_LENGTH ?
- ehResponse->payloadSize : MAX_RESPONSE_LENGTH);
+ OCStackResult result;
+ if((result = OCConvertPayload(ehResponse->payload, &responseInfo.info.payload,
+ &responseInfo.info.payloadSize))
+ != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "Error converting payload");
+ return result;
+ }
+
+ if(responseInfo.info.payloadSize > MAX_RESPONSE_LENGTH)
+ {
+ OICFree(responseInfo.info.payload);
+ OC_LOG(ERROR, TAG, "Payload too long!");
+ return OC_STACK_INVALID_PARAM;
+ }
+ }
+ else
+ {
+ responseInfo.info.payload = NULL;
+ responseInfo.info.payloadSize = 0;
}
- OICStrcat(payload, sizeof(payload), OC_JSON_SUFFIX);
- responseInfo.info.payload = (CAPayload_t)payload;
#ifdef WITH_PRESENCE
//TODO: Add other connectivity types to CAConnTypes[] when enabled
}
#endif
+ OICFree(responseInfo.info.payload);
OICFree(responseInfo.info.token);
OICFree(responseInfo.info.options);
//Delete the request
OCStackResult stackRet = OC_STACK_ERROR;
OCServerRequest * serverRequest = NULL;
OCServerResponse * serverResponse = NULL;
- uint16_t bufferNeeded = 0;
if(!ehResponse || !ehResponse->payload)
{
return OC_STACK_INVALID_PARAM;
}
- OC_LOG_V(INFO, TAG, "Inside HandleAggregateResponse: %s", ehResponse->payload);
+ OC_LOG(INFO, TAG, "Inside HandleAggregateResponse");
serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
serverResponse = GetServerResponseUsingHandle((OCServerRequest *)ehResponse->requestHandle);
return stackRet;
}
VERIFY_NON_NULL(serverResponse);
- VERIFY_NON_NULL(serverResponse->payload);
}
- // If there is more than 1 response, then we need to allow for a null-termination
- // in the server response payload buffer AND the JSON response separator
- bufferNeeded = ehResponse->payloadSize + 1;
- if (serverRequest->numResponses > 1)
+ if(serverResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION ||
+ ehResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
{
- bufferNeeded += strlen(OC_JSON_SEPARATOR_STR);
+ stackRet = OC_STACK_ERROR;
+ OC_LOG(ERROR, TAG, PCF("Error adding payload, as it was the incorrect type"));
+ goto exit;
}
- if(serverResponse->remainingPayloadSize >= bufferNeeded)
- {
- OC_LOG(ERROR, TAG, PCF("There is room in response buffer"));
- // append
- // allocated size of the payload is assumed, since a search of the code
- // shows that it is OICCalloc'ed to this size in AddServerResponse above
- OICStrcatPartial(serverResponse->payload,
- MAX_RESPONSE_LENGTH,
- ehResponse->payload,
- serverResponse->remainingPayloadSize);
- OC_LOG_V(INFO, TAG, "Current aggregated response ...%s", serverResponse->payload);
- serverResponse->remainingPayloadSize -= strlen((char *)ehResponse->payload);
- (serverRequest->numResponses)--;
- if(serverRequest->numResponses == 0)
- {
- OC_LOG(INFO, TAG, PCF("This is the last response fragment"));
- ehResponse->payload = serverResponse->payload;
- ehResponse->payloadSize = strlen((char *) serverResponse->payload) + 1;
- stackRet = HandleSingleResponse(ehResponse);
- //Delete the request and response
- FindAndDeleteServerRequest(serverRequest);
- FindAndDeleteServerResponse(serverResponse);
- }
- else
- {
- OC_LOG(INFO, TAG, PCF("More response fragments to come"));
- OICStrcatPartial(serverResponse->payload,
- MAX_RESPONSE_LENGTH,
- OC_JSON_SEPARATOR_STR,
- serverResponse->remainingPayloadSize);
- OC_LOG_V(INFO, TAG, "Current aggregated response ...%s", serverResponse->payload);
- serverResponse->remainingPayloadSize -= strlen(OC_JSON_SEPARATOR_STR);
- stackRet = OC_STACK_OK;
- }
- }
- else
+
+ OCRepPayloadAppend((OCRepPayload*)serverResponse->payload,
+ (OCRepPayload*)ehResponse->payload);
+
+ (serverRequest->numResponses)--;
+
+ if(serverRequest->numResponses == 0)
{
- OC_LOG(ERROR, TAG, PCF("No room in response buffer"));
+ OC_LOG(INFO, TAG, PCF("This is the last response fragment"));
+ ehResponse->payload = serverResponse->payload;
+ stackRet = HandleSingleResponse(ehResponse);
//Delete the request and response
FindAndDeleteServerRequest(serverRequest);
FindAndDeleteServerResponse(serverResponse);
- stackRet = OC_STACK_NO_MEMORY;
+ }
+ else
+ {
+ OC_LOG(INFO, TAG, PCF("More response fragments to come"));
+ stackRet = OC_STACK_OK;
}
}
exit:
#include "secureresourcemanager.h"
#include "cacommon.h"
#include "cainterface.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
#ifdef WITH_ARDUINO
#include "Time.h"
#include "coap_time.h"
#include "utlist.h"
#include "pdu.h"
-#include "cJSON.h"
#ifndef ARDUINO
#include <arpa/inet.h>
#define MAX_OBSERVE_AGE (0x2FFFFUL)
#define MILLISECONDS_PER_SECOND (1000)
-/**
- * Parse the presence payload and extract various parameters.
- * Note: Caller should invoke OICFree after done with resType pointer.
- *
- * @param payload Presence payload.
- * @param seqNum Sequence number.
- * @param maxAge Time To Live (in seconds).
- * @param resType Resource type.
- */
-void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge,
- OCPresenceTrigger *presenceTrigger, char** resType);
//-----------------------------------------------------------------------------
// Private internal function prototypes
static OCStackResult verifyUriQueryLength(const char * inputUri,
uint16_t uriLen);
-/**
- * Determine if a request/response must be sent in a block transfer because it is too large to be
- * sent in a single PDU. This function can be used for either a request or a response.
- * Note: Either the request or response parameter should be non-NULL (i.e. only one, not both).
- *
- * @param request NULL or pointer to request.
- * @param response NULL or pointer to response.
- * @param size 0 or size of the request/response. If 0, strlen is used for determining
- * the length of the request/response.
- *
- * @return
- * false - packet transfer NOT required (i.e. normal request/response).
- * true - packet transfer required (i.e. block transfer needed).
- */
-static bool OCIsPacketTransferRequired(const char *request, const char *response, size_t size);
-
/*
* Attempts to initialize every network interface that the CA Layer might have compiled in.
*
if(observer)
{
result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) NULL,
- OC_REST_NOMETHOD, (OCResourceHandle) NULL, NULL, NULL, 0,
+ OC_REST_NOMETHOD, (OCResourceHandle) NULL, NULL, NULL, 0, 0,
NULL, OC_OBSERVE_DEREGISTER, observer->observeId);
if(result != OC_STACK_OK)
{
if(observer->failedCommCount >= MAX_OBSERVER_FAILED_COMM)
{
result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) NULL,
- OC_REST_NOMETHOD, (OCResourceHandle) NULL, NULL, NULL, 0,
+ OC_REST_NOMETHOD, (OCResourceHandle) NULL, NULL, NULL, 0, 0,
NULL, OC_OBSERVE_DEREGISTER, observer->observeId);
if(result != OC_STACK_OK)
{
*
* requestUri must be a char array of size CA_MAX_URI_LENGTH
*/
-static int FormCanonicalPresenceUri(const CAEndpoint_t *endpoint, char *resourceUri, char *presenceUri)
+static int FormCanonicalPresenceUri(const CAEndpoint_t *endpoint, char *resourceUri,
+ char *presenceUri)
{
VERIFY_NON_NULL(endpoint , FATAL, OC_STACK_INVALID_PARAM);
VERIFY_NON_NULL(resourceUri, FATAL, OC_STACK_INVALID_PARAM);
endpoint->port, OC_PRESENCE_URI);
}
-void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge,
- OCPresenceTrigger *presenceTrigger, char** resType)
-{
- if(!payload || !seqNum || !maxAge || !presenceTrigger || !resType)
- {
- return;
- }
-
- cJSON *repObj = cJSON_Parse(payload);
- cJSON *ocObj = NULL;
- cJSON *presenceObj = NULL;
- cJSON *seqNumObj = NULL;
- cJSON *maxAgeObj = NULL;
- cJSON *triggerObj = NULL;
- cJSON *resObj = NULL;
- if(repObj)
- {
- ocObj = cJSON_GetObjectItem(repObj, OC_RSRVD_OC);
- if(ocObj)
- {
- //Presence payloads should only carry one JSON payload. The first
- // & only array item is retrieved.
- presenceObj = cJSON_GetArrayItem(ocObj, 0);
- if(presenceObj)
- {
- seqNumObj = cJSON_GetObjectItem(presenceObj, OC_RSRVD_NONCE);
- if(seqNumObj)
- {
- *seqNum = (uint32_t)seqNumObj->valuedouble;
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("Nonce (AKA SeqNum) not found in"
- " JSON Presence Payload."));
- goto exit;
- }
- maxAgeObj = cJSON_GetObjectItem(presenceObj, OC_RSRVD_TTL);
- if(maxAgeObj)
- {
- *maxAge = maxAgeObj->valueint;
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("TTL (AKA MaxAge) not found in"
- " JSON Presence Payload."));
- goto exit;
- }
- triggerObj = cJSON_GetObjectItem(presenceObj,
- OC_RSRVD_TRIGGER);
- if(triggerObj)
- {
- char * triggerStr = triggerObj->valuestring;
- *presenceTrigger = convertTriggerStringToEnum(triggerStr);
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("Trigger Reason not found in"
- " JSON Presence Payload."));
- goto exit;
- }
- resObj = cJSON_GetObjectItem(presenceObj,
- OC_RSRVD_RESOURCE_TYPE);
- if(resObj)
- {
- *resType = OICStrdup(resObj->valuestring);
- if(!*resType)
- {
- goto exit;
- }
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("Resource Type not found in"
- " JSON Presence Payload."));
- goto exit;
- }
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("JSON Presence Object not found in"
- " Presence Payload."));
- OICFree(*resType);
- goto exit;
- }
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("JSON Presence Payload does not contain a"
- " valid \"oic\" JSON representation."));
- OICFree(*resType);
- goto exit;
- }
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("JSON Presence Payload does map to a valid JSON"
- " representation."));
- OICFree(*resType);
- goto exit;
- }
-
-exit:
- cJSON_Delete(repObj);
-}
OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint,
const CAResponseInfo_t *responseInfo)
OCClientResponse response;
OCStackResult result = OC_STACK_ERROR;
uint32_t maxAge = 0;
- OCPresenceTrigger presenceTrigger = OC_PRESENCE_TRIGGER_CHANGE;
int uriLen;
char presenceUri[CA_MAX_URI_LENGTH];
goto exit;
}
- response.resJSONPayload = responseInfo->info.payload;
+ response.payload = NULL;
response.result = OC_STACK_OK;
CopyEndpointToDevAddr(endpoint, &response.devAddr);
if (responseInfo->info.payload)
{
- parsePresencePayload(responseInfo->info.payload,
- &(response.sequenceNumber),
- &maxAge,
- &presenceTrigger,
- &resourceTypeName);
+ result = OCParsePayload(&response.payload, responseInfo->info.payload,
+ responseInfo->info.payloadSize);
+
+ if(result != OC_STACK_OK || response.payload->type != PAYLOAD_TYPE_PRESENCE)
+ {
+ OC_LOG(ERROR, TAG, PCF("Presence parse failed"));
+ goto exit;
+ }
+ response.sequenceNumber = ((OCPresencePayload*)response.payload)->sequenceNumber;
+ resourceTypeName = ((OCPresencePayload*)response.payload)->resourceType;
+ maxAge = ((OCPresencePayload*)response.payload)->maxAge;
}
if (presenceSubscribe)
cbNode->sequenceNumber = response.sequenceNumber;
// Ensure that a filter is actually applied.
- if(resourceTypeName && cbNode->filterResourceType)
+ if( resourceTypeName && cbNode->filterResourceType)
{
if(!findResourceType(cbNode->filterResourceType, resourceTypeName))
{
VERIFY_NON_NULL_NR(endPoint, FATAL);
VERIFY_NON_NULL_NR(responseInfo, FATAL);
VERIFY_NON_NULL_NR(responseInfo->info.resourceUri, FATAL);
+ OC_LOG(INFO, TAG, PCF("Enter HandleCAResponses"));
if(strcmp(responseInfo->info.resourceUri, OC_PRESENCE_URI) == 0)
{
ClientCB *cbNode = GetClientCB(responseInfo->info.token,
responseInfo->info.tokenLength, NULL, NULL);
- OC_LOG_V(DEBUG, TAG, "Response has the token %s", responseInfo->info.token);
+ OC_LOG(DEBUG, TAG, PCF("Response has the token:"));
+ OC_LOG_BUFFER(DEBUG, TAG, (const uint8_t*)responseInfo->info.token, responseInfo->info.tokenLength);
ResourceObserver * observer = GetObserverUsingToken (responseInfo->info.token,
responseInfo->info.tokenLength);
response.resourceUri = responseInfo->info.resourceUri;
response.result = CAToOCStackResult(responseInfo->result);
- response.resJSONPayload = (const char*)responseInfo->info.payload;
+ if(responseInfo->info.payload &&
+ responseInfo->info.payloadSize &&
+ OC_STACK_OK != OCParsePayload(&response.payload, responseInfo->info.payload,
+ responseInfo->info.payloadSize))
+ {
+ OC_LOG(ERROR, TAG, PCF("Error converting payload"));
+ return;
+ }
+
response.numRcvdVendorSpecificHeaderOptions = 0;
if(responseInfo->info.numOptions > 0)
{
cbNode->TTL = GetTicks(MAX_CB_TIMEOUT_SECONDS *
MILLISECONDS_PER_SECOND);
}
+ OCPayloadDestroy(response.payload);
}
//Need to send ACK when the response is CON
return;
}
- OC_LOG_V(INFO, TAG, PCF("Received payload: %s\n"), (char*)responseInfo->info.payload);
OC_LOG(INFO, TAG, PCF("Exit HandleCAResponses"));
}
//copy request payload
if (requestInfo->info.payload)
{
- size_t payloadLen = strlen(requestInfo->info.payload);
- serverRequest.reqTotalSize = payloadLen + 1;
- OICStrcpy(serverRequest.reqJSONPayload, sizeof(serverRequest.reqJSONPayload),
- requestInfo->info.payload);
+ serverRequest.reqTotalSize = requestInfo->info.payloadSize;
+ memcpy (&(serverRequest.payload), requestInfo->info.payload,
+ requestInfo->info.payloadSize);
}
else
{
- serverRequest.reqTotalSize = 1;
- serverRequest.reqJSONPayload[0] = '\0';
+ serverRequest.reqTotalSize = 0;
}
switch (requestInfo->method)
protocolRequest->method, protocolRequest->numRcvdVendorSpecificHeaderOptions,
protocolRequest->observationOption, protocolRequest->qos,
protocolRequest->query, protocolRequest->rcvdVendorSpecificHeaderOptions,
- protocolRequest->reqJSONPayload, protocolRequest->requestToken,
+ protocolRequest->payload, protocolRequest->requestToken,
protocolRequest->tokenLength,
protocolRequest->resourceUrl, protocolRequest->reqTotalSize,
&protocolRequest->devAddr);
// Free memory dynamically allocated for resources
deleteAllResources();
DeleteDeviceInfo();
+ DeletePlatformInfo();
CATerminate();
// Remove all observers
DeleteObserverList();
// TODO after BeachHead delivery: consolidate into single SRMDeInit()
SRMDeInitPolicyEngine();
+
stackState = OC_STACK_UNINITIALIZED;
return OC_STACK_OK;
}
OCMethod method,
const char *requestUri,
const OCDevAddr *destination,
- const char *request,
+ OCPayload* payload,
OCConnectivityType connectivityType,
OCQualityOfService qos,
OCCallbackData *cbData,
goto exit;
}
- if ((request) && (strlen(request) > MAX_REQUEST_LENGTH))
- {
- result = OC_STACK_INVALID_PARAM;
- goto exit;
- }
-
/*
* Support original behavior with address on resourceUri argument.
*/
requestInfo.info.token = token;
requestInfo.info.tokenLength = tokenLength;
requestInfo.info.resourceUri = resourceUri;
- requestInfo.info.payload = (char *)request;
+
if ((method == OC_REST_OBSERVE) || (method == OC_REST_OBSERVE_ALL))
{
result = CreateObserveHeaderOption (&(requestInfo.info.options),
// create remote endpoint
result = OCCreateEndpoint(devAddr, &endpoint);
+ if(payload)
+ {
+ if((result =
+ OCConvertPayload(payload, &requestInfo.info.payload, &requestInfo.info.payloadSize))
+ != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, PCF("Failed to create CBOR Payload"));
+ goto exit;
+ }
+ }
+ else
+ {
+ requestInfo.info.payload = NULL;
+ requestInfo.info.payloadSize = 0;
+ }
+
+
+
if (result != OC_STACK_OK)
{
OC_LOG(ERROR, TAG, PCF("CACreateEndpoint error"));
}
OICFree(resHandle);
}
+
+ // This is the owner of the payload object, so we free it
+ OCPayloadDestroy(payload);
OICFree(devAddr);
OICFree(resourceUri);
OICFree(resourceType);
clientResponse.result = OC_STACK_PRESENCE_TIMEOUT;
clientResponse.devAddr = *cbNode->devAddr;
FixUpClientResponse(&clientResponse);
- clientResponse.resJSONPayload = NULL;
+ clientResponse.payload = NULL;
// Increment the TTLLevel (going to a next state), so we don't keep
// sending presence notification to client.
OCNotifyListOfObservers (OCResourceHandle handle,
OCObservationId *obsIdList,
uint8_t numberOfIds,
- const char *notificationJSONPayload,
+ const OCRepPayload *payload,
OCQualityOfService qos)
{
OC_LOG(INFO, TAG, PCF("Entering OCNotifyListOfObservers"));
VERIFY_NON_NULL(handle, ERROR, OC_STACK_ERROR);
VERIFY_NON_NULL(obsIdList, ERROR, OC_STACK_ERROR);
- VERIFY_NON_NULL(notificationJSONPayload, ERROR, OC_STACK_ERROR);
+ VERIFY_NON_NULL(payload, ERROR, OC_STACK_ERROR);
// Verify that the resource exists
resPtr = findResource ((OCResource *) handle);
incrementSequenceNumber(resPtr);
}
return (SendListObserverNotification(resPtr, obsIdList, numberOfIds,
- notificationJSONPayload, maxAge, qos));
+ payload, maxAge, qos));
}
OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse)
VERIFY_NON_NULL(ehResponse, ERROR, OC_STACK_INVALID_PARAM);
VERIFY_NON_NULL(ehResponse->requestHandle, ERROR, OC_STACK_INVALID_PARAM);
- // TODO: Placeholder for creating a response entry when implementing
- // block transfer feature
-
- // If a response payload is present, check if block transfer is required
- if (ehResponse->payload && OCIsPacketTransferRequired(NULL,
- (const char *)ehResponse->payload, ehResponse->payloadSize))
- {
- OC_LOG(INFO, TAG, PCF("Block transfer required"));
-
- // Persistent response buffer is needed for block transfer
- if (!ehResponse->persistentBufferFlag)
- {
- OC_LOG(WARNING, TAG, PCF("Persistent response buffer required"));
- return OC_STACK_PERSISTENT_BUFFER_REQUIRED;
- }
- // TODO: Placeholder for block transfer handling
- // TODO: Placeholder for setting the the response handle in the OCServerResponse struct
- // when implementing the block transfer feature
- }
- else
+ // Normal response
+ // Get pointer to request info
+ serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
+ if(serverRequest)
{
- // Normal response
- // Get pointer to request info
- serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
- if(serverRequest)
- {
- result = serverRequest->ehResponseHandler(ehResponse);
- }
+ result = serverRequest->ehResponseHandler(ehResponse);
}
+
return result;
}
return pointer;
}
-bool OCIsPacketTransferRequired(const char *request, const char *response, size_t size)
-{
- bool result = false;
-
- // Determine if we are checking a request or a response
- if (request)
- {
- // If size is greater than 0, use it for the request size value, otherwise
- // assume request is null terminated and use strlen for size value
- if ((size > MAX_REQUEST_LENGTH) || (strlen(request) > MAX_REQUEST_LENGTH))
- {
- result = true;
- }
- }
- else if (response)
- {
- // If size is greater than 0, use it for the response size value, otherwise
- // assume response is null terminated and use strlen for size value
- if ((size > MAX_RESPONSE_LENGTH) || (strlen(response) > MAX_RESPONSE_LENGTH))
- {
- result = true;
- }
- }
- return result;
-}
-
/*
* This function splits the uri using the '?' delimiter.
* "uriWithoutQuery" is the block of characters between the beginning
{
int idx;
- unsigned char *responseJson;
- responseJson = (unsigned char *) OICMalloc(
- (unsigned int) (strlen((char *) clientResponse->resJSONPayload)
- + 1));
+ unsigned char *responseJson = NULL;
+ // TODO: Figure out what this does, change implementation
+ //responseJson = (unsigned char *) OICMalloc(
+ // (unsigned int) (strlen((char *) clientResponse->resJSONPayload)
+ // + 1));
if( responseJson == NULL )
return OC_STACK_DELETE_TRANSACTION;
// We need the body of response.
// Copy the body from the response
- strcpy((char *) responseJson,
- ((char *) clientResponse->resJSONPayload + OC_JSON_PREFIX_LEN));
- idx = strlen((char *) responseJson) - OC_JSON_SUFFIX_LEN;
+ // TODO: Taken out
+ //strcpy((char *) responseJson,
+ // ((char *) clientResponse->resJSONPayload + OC_JSON_PREFIX_LEN));
+ //idx = strlen((char *) responseJson) - OC_JSON_SUFFIX_LEN;
// And insert NULL at the end of body.
(responseJson[idx]) = 0;
OCEntityHandlerResponse response = { 0 };
response.ehResult = OC_EH_OK;
- response.payload = (char*)responseJson;
- response.payloadSize = (unsigned int) strlen((char *) responseJson) + 1;
+ // TODO: Removing payload size, waht goes here?
+ // response.payload = (char*)responseJson;
+ //response.payloadSize = (unsigned int) strlen((char *) responseJson) + 1;
response.persistentBufferFlag = 0;
response.requestHandle = (OCRequestHandle) info->ehRequest;
response.resourceHandle = (OCResourceHandle) info->collResource;
cbdata.cd = NULL;
cbdata.context = (void*)DEFAULT_CONTEXT_VALUE;
- return OCDoResource(handle, OC_REST_PUT, targetUri,
- NULL, (char *) action, CT_ADAPTER_IP, OC_NA_QOS, &cbdata, NULL, 0);
+ // TODO: disabled since this is no longer compatible
+ return OC_STACK_NOTIMPL;
+ //return OCDoResource(handle, OC_REST_PUT, targetUri,
+ // NULL, (char *) action, CT_ADAPTER_IP, OC_NA_QOS, &cbdata, NULL, 0);
}
OCStackResult DoAction(OCResource* resource, OCActionSet* actionset,
char *jsonResponse;
- stackRet = ExtractKeyValueFromRequest((char *) ehRequest->reqJSONPayload,
- &doWhat, &details);
+ stackRet = OC_STACK_NOTIMPL;
+ // TODO: Fix?
+ //stackRet = ExtractKeyValueFromRequest((char *) ehRequest->reqJSONPayload,
+ // &doWhat, &details);
if(stackRet != OC_STACK_OK)
{
response.ehResult = OC_EH_OK;
else
response.ehResult = OC_EH_ERROR;
- response.payload = (char*)buffer;
- response.payloadSize = bufferLength + 1;
+ // TODO: Fix
+ //response.payload = (char*)buffer;
+ //response.payloadSize = bufferLength + 1;
response.persistentBufferFlag = 0;
response.requestHandle =
(OCRequestHandle) ehRequest->requestHandle;
response.ehResult = OC_EH_OK;
else
response.ehResult = OC_EH_ERROR;
- response.payload = (char *)buffer;
- response.payloadSize = bufferLength + 1;
+ // TODO: Implement
+ //response.payload = (char *)buffer;
+ //response.payloadSize = bufferLength + 1;
response.persistentBufferFlag = 0;
response.requestHandle =
(OCRequestHandle) ehRequest->requestHandle;
uint8_t numExpectedResources = 0;
EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numExpectedResources));
-
+
OCResourceHandle handle0;
EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle0,
"core.led",
EXPECT_EQ(OC_STACK_OK, OCStop());
}
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
- void parsePresencePayload(char* payload, uint32_t* seqNum,
- uint32_t* maxAge, OCPresenceTrigger* presenceTrigger, char** resType);
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-TEST(StackPresence, ParsePresencePayload)
-{
- itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
- OC_LOG(INFO, TAG, "Starting ParsePresencePayload test");
-
- char payload[100];
- uint32_t seqNum = 0, maxAge = 0;
- OCPresenceTrigger presenceTrigger = OC_PRESENCE_TRIGGER_CHANGE;
- char * resType = NULL;
-
- //Good Scenario
- strncpy(payload, "{\"oic\":[{\"ttl\":99,\"non\":100,\"trg\":"
- "\"delete\",\"rt\":\"presence\"}]}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge,
- &presenceTrigger, &resType);
- EXPECT_TRUE(100 == seqNum);
- EXPECT_TRUE(99 == maxAge);
- EXPECT_TRUE(OC_PRESENCE_TRIGGER_DELETE == presenceTrigger);
- EXPECT_TRUE(NULL != resType);
- EXPECT_STREQ("presence", resType);
- OICFree(resType);
-
- presenceTrigger = OC_PRESENCE_TRIGGER_CHANGE;
-
- //Bad Scenario -- should not result in Seg Fault
- parsePresencePayload(payload, NULL, &maxAge, &presenceTrigger, &resType);
-
- //Bad Scenario
- seqNum = 0; maxAge = 0; resType = NULL;
- strncpy(payload, "{abracadabra}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &presenceTrigger, &resType);
- EXPECT_TRUE(0 == seqNum);
- EXPECT_TRUE(0 == maxAge);
- EXPECT_TRUE(OC_PRESENCE_TRIGGER_CHANGE == presenceTrigger);
- EXPECT_TRUE(NULL == resType);
- EXPECT_EQ(NULL, resType);
- OICFree(resType);
-
- //Bad Scenario
- seqNum = 0; maxAge = 0; resType = NULL;
- strncpy(payload, "{\"oic\":[100]}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &presenceTrigger, &resType);
- EXPECT_TRUE(0 == seqNum);
- EXPECT_TRUE(0 == maxAge);
- EXPECT_TRUE(OC_PRESENCE_TRIGGER_CHANGE == presenceTrigger);
- EXPECT_TRUE(NULL == resType);
- EXPECT_EQ(NULL, resType);
- OICFree(resType);
-
- //Bad Scenario
- seqNum = 0; maxAge = 0; resType = NULL;
- strncpy(payload, "{\"oic\":[]}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &presenceTrigger, &resType);
- EXPECT_TRUE(0 == seqNum);
- EXPECT_TRUE(0 == maxAge);
- EXPECT_TRUE(OC_PRESENCE_TRIGGER_CHANGE == presenceTrigger);
- EXPECT_TRUE(NULL == resType);
- EXPECT_EQ(NULL, resType);
- OICFree(resType);
-
- //Bad Scenario
- strncpy(payload, "{:]}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &presenceTrigger, &resType);
- EXPECT_TRUE(0 == seqNum);
- EXPECT_TRUE(0 == maxAge);
- EXPECT_TRUE(OC_PRESENCE_TRIGGER_CHANGE == presenceTrigger);
- EXPECT_TRUE(NULL == resType);
- EXPECT_EQ(NULL, resType);
- OICFree(resType);
-
- //Bad Scenario
- strncpy(payload, "{:[presence}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &presenceTrigger, &resType);
- EXPECT_TRUE(0 == seqNum);
- EXPECT_TRUE(0 == maxAge);
- EXPECT_TRUE(OC_PRESENCE_TRIGGER_CHANGE == presenceTrigger);
- EXPECT_TRUE(NULL == resType);
- EXPECT_EQ(NULL, resType);
- OICFree(resType);
-}
-
TEST(PODTests, OCHeaderOption)
{
EXPECT_TRUE(std::is_pod<OCHeaderOption>::value);
private:
void listeningFunc();
std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
- std::string assembleSetResourcePayload(const OCRepresentation& attributes);
+ OCPayload* assembleSetResourcePayload(const OCRepresentation& attributes);
OCHeaderOption* assembleHeaderOptions(OCHeaderOption options[],
const HeaderOptions& headerOptions);
std::thread m_listeningThread;
#ifndef __INTEL_OCAPI_H_2014_07_10
#define __INTEL_OCAPI_H_2014_07_10
+
#include <string>
#include <sstream>
#include <vector>
#include <OCException.h>
-namespace cereal
-{
- class access;
-}
-
namespace OC
{
DefaultChild
};
- // The consumer requires resource info to be printed in 2 different ways, both with the "oc":[]
- // and without. This enum is used to differentiate between the two situations. When the
- // serialize is called with Include OC, we encode OC, otherwise we skip it and return just the
- // contents of the array.
- enum class OCInfoFormat
- {
- IncludeOC,
- ExcludeOC
- };
-
class MessageContainer
{
public:
- void setJSONRepresentation(const std::string& payload);
+ void setPayload(const OCPayload* rep);
+
+ void setPayload(const OCDevicePayload* rep);
- void setJSONRepresentation(const char* payload);
+ void setPayload(const OCPlatformPayload* rep);
- std::string getJSONRepresentation(OCInfoFormat f) const;
+ void setPayload(const OCRepPayload* rep);
+
+ OCRepPayload* getPayload() const;
const std::vector<OCRepresentation>& representations() const;
virtual ~OCRepresentation(){}
- std::string getJSONRepresentation() const;
+ OCRepPayload* getPayload() const;
void addChild(const OCRepresentation&);
void setResourceTypes(const std::vector<std::string>& resourceTypes);
+ void addResourceType(const std::string& str);
+
const std::vector<std::string>& getResourceInterfaces() const;
void setResourceInterfaces(const std::vector<std::string>& resourceInterfaces);
+ void addResourceInterface(const std::string& str);
+
bool emptyData() const;
int numberOfAttributes() const;
const AttributeItem operator[](const std::string& key) const;
private:
friend class OCResourceResponse;
- friend class cereal::access;
-
+ friend class MessageContainer;
+
+ template<typename T>
+ void payload_array_helper(const OCRepPayloadValue* pl, size_t depth);
+ template<typename T>
+ T payload_array_helper_copy(size_t index, const OCRepPayloadValue* pl);
+ void setPayload(const OCRepPayload* payload);
+ void setPayloadArray(const OCRepPayloadValue* pl);
+ void getPayloadArray(OCRepPayload* payload,
+ const OCRepresentation::AttributeItem& item) const;
// the root node has a slightly different JSON version
// based on the interface type configured in ResourceResponse.
// This allows ResourceResponse to set it, so that the save function
m_interfaces(interfaces)
{}*/
private:
- friend class cereal::access;
- template <class Archive>
- void save(Archive& ar) const;
-
- template<class Archive>
- void load(Archive& ar);
-
std::vector<std::string>& m_types;
std::vector<std::string>& m_interfaces;
};
- template<class Archive, class Val>
- static void optional_load(Archive& ar, Val&& v);
-
- template<class Archive>
- void save(Archive& ar) const;
-
- template<class Archive>
- void load(Archive& ar);
-
private:
std::string m_uri;
std::vector<OCRepresentation> m_children;
m_requestType = requestType;
}
- void setPayload(const std::string& requestPayload);
+ void setPayload(OCPayload* requestPayload);
void setQueryParams(QueryParamsMap& queryParams)
{
private:
friend class InProcServerWrapper;
- std::string getPayload() const
+ OCRepPayload* getPayload() const
{
MessageContainer inf;
OCRepresentation first(m_representation);
}
- return inf.getJSONRepresentation(OCInfoFormat::ExcludeOC);
+ return inf.getPayload();
}
public:
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include <cereal/cereal.hpp>
-#include <cereal/types/memory.hpp>
-#include <cereal/types/vector.hpp>
-#include <cereal/archives/json.hpp>
-
#include <StringConstants.h>
+#include "ocpayload.h"
+#include "ocrandom.h"
namespace OC
{
class ListenOCContainer
{
private:
+ static std::vector<std::string> StringLLToVector(OCStringLL* ll)
+ {
+ std::vector<std::string> strs;
+ while(ll)
+ {
+ strs.push_back(ll->value);
+ ll = ll->next;
+ }
+ return strs;
+ }
+
+ public:
+ ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
+ const OCDevAddr& devAddr, OCDiscoveryPayload* payload)
+ : m_clientWrapper(cw), m_devAddr(devAddr)
+ {
+ OCResourcePayload* res = payload->resources;
+
+ while(res)
+ {
+ char uuidString[UUID_STRING_SIZE];
+ if(OCConvertUuidToString(res->sid, uuidString) != RAND_UUID_OK)
+ {
+ uuidString[0]= '\0';
+ }
+
+ m_resources.push_back(std::shared_ptr<OC::OCResource>(
+ new OC::OCResource(m_clientWrapper, m_devAddr,
+ std::string(res->uri),
+ std::string(uuidString),
+ (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+ StringLLToVector(res->types),
+ StringLLToVector(res->interfaces)
+ )));
+ res = res->next;
+ }
+
+ }
+
+ const std::vector<std::shared_ptr<OCResource>>& Resources() const
+ {
+ return m_resources;
+ }
+ private:
+ std::vector<std::shared_ptr<OC::OCResource>> m_resources;
+ std::weak_ptr<IClientWrapper> m_clientWrapper;
+ const OCDevAddr& m_devAddr;
+ };
+ /*
+ class ListenOCContainer
+ {
+ private:
enum class OCSecureType
{
NotSecure,
}
}
}
- std::vector<std::shared_ptr<OC::OCResource>> m_resources;
- std::weak_ptr<IClientWrapper> m_clientWrapper;
- const OCDevAddr& m_devAddr;
};
+*/
}
+++ /dev/null
-/*! \file OicJsonSerializer.hpp
- \brief JSON input and output archives.
-Note: this has been customized by Intel(R) for usage in the OIC project.
-Nearly the entire file is from Cereal (see copyright notice below) other than specified
-below
-Added:
-#include of AttributeValue Type
-JSONOutputArchive::saveValue() to add JSON null value
-loadAttributeValues to get attribute values out of a map (implemented in OCRepresentation)
-
-*/
-/*
- Copyright (c) 2014, Randolph Voorhies, Shane Grant
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of cereal nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef CEREAL_ARCHIVES_JSON_HPP_
-#define CEREAL_ARCHIVES_JSON_HPP_
-
-#include <AttributeValue.h>
-#include <cereal/cereal.hpp>
-#include <cereal/details/util.hpp>
-namespace cereal
-{
- //! An exception thrown when rapidjson fails an internal assertion
- /*! @ingroup Utility */
- struct RapidJSONException : Exception
- { RapidJSONException( const char * what_ ) : Exception( what_ ) {} };
-}
-
-// Override rapidjson assertions to throw exceptions by default
-#ifndef RAPIDJSON_ASSERT
-#define RAPIDJSON_ASSERT(x) if(!(x)){ \
- throw ::cereal::RapidJSONException("rapidjson internal assertion failure: " #x); }
-#endif // RAPIDJSON_ASSERT
-
-#include <cereal/external/rapidjson/writer.h>
-#include <cereal/external/rapidjson/genericstream.h>
-#include <cereal/external/rapidjson/reader.h>
-#include <cereal/external/rapidjson/document.h>
-#include <cereal/external/base64.hpp>
-
-#include <limits>
-#include <sstream>
-#include <stack>
-#include <vector>
-#include <string>
-
-namespace cereal
-{
- // ######################################################################
- //! An output archive designed to save data to JSON
- /*! This archive uses RapidJSON to build serialized data to JSON.
-
- JSON archives provides a human readable output but at decreased
- performance (both in time and space) compared to binary archives.
-
- JSON benefits greatly from name-value pairs, which if present, will
- name the nodes in the output. If these are not present, each level
- of the output will be given an automatically generated delimited name.
-
- The precision of the output archive controls the number of decimals output
- for floating point numbers and should be sufficiently large (i.e. at least 20)
- if there is a desire to have binary equality between the numbers output and
- those read in. In general you should expect a loss of precision when going
- from floating point to text and back.
-
- JSON archives do not output the size information for any dynamically sized structure
- and instead infer it from the number of children for a node. This means that data
- can be hand edited for dynamic sized structures and will still be readable. This
- is accomplished through the cereal::SizeTag object, which will cause the archive
- to output the data as a JSON array (e.g. marked by [] instead of {}), which indicates
- that the container is variable sized and may be edited.
-
- \ingroup Archives */
- class JSONOutputArchive : public OutputArchive<JSONOutputArchive>
- {
- enum class NodeType { StartObject, InObject, StartArray, InArray };
-
- typedef rapidjson::GenericWriteStream WriteStream;
- typedef rapidjson::Writer<WriteStream> JSONWriter;
-
- public:
- /*! @name Common Functionality
- Common use cases for directly interacting with an JSONOutputArchive */
- //! @{
-
- //! A class containing various advanced options for the JSON archive
- class Options
- {
- public:
- //! Default options
- static Options Default(){ return Options(); }
-
- //! Specify specific options for the JSONOutputArchive
- /*! @param precision The precision used for floating point numbers*/
- explicit Options( int precision = std::numeric_limits<double>::max_digits10) :
- itsPrecision( precision ) { }
-
- private:
- friend class JSONOutputArchive;
- int itsPrecision;
- };
-
- //! Construct, outputting to the provided stream
- /*! @param stream The stream to output to.
- @param options The JSON specific options to use. See the Options struct
- for the values of default parameters */
- JSONOutputArchive(std::ostream & stream, Options const & options = Options::Default() ) :
- OutputArchive<JSONOutputArchive>(this),
- itsWriteStream(stream),
- itsWriter(itsWriteStream, options.itsPrecision),
- itsNextName(nullptr)
- {
- itsNameCounter.push(0);
- itsNodeStack.push(NodeType::StartObject);
- }
-
- //! Destructor, flushes the JSON
- ~JSONOutputArchive()
- {
- itsWriter.EndObject();
- }
-
- //! Saves some binary data, encoded as a base64 string, with an optional name
- /*! This will create a new node, optionally named, and insert a value that consists of
- the data encoded as a base64 string */
- void saveBinaryValue( const void * data, size_t size, const char * name = nullptr )
- {
- setNextName( name );
- writeName();
-
- auto base64string = base64::encode( reinterpret_cast<const unsigned char *>( data ), size );
- saveValue( base64string );
- };
-
- //! @}
- /*! @name Internal Functionality
- Functionality designed for use by those requiring control over the inner mechanisms of
- the JSONOutputArchive */
- //! @{
-
- //! Starts a new node in the JSON output
- /*! The node can optionally be given a name by calling setNextName prior
- to creating the node
-
- Nodes only need to be started for types that are themselves objects or arrays */
- void startNode()
- {
- writeName();
- itsNodeStack.push(NodeType::StartObject);
- itsNameCounter.push(0);
- }
-
- //! Designates the most recently added node as finished
- void finishNode()
- {
- // if we ended up serializing an empty object or array, writeName
- // will never have been called - so start and then immediately end
- // the object/array.
- //
- // We'll also end any object/arrays we happen to be in
- switch(itsNodeStack.top())
- {
- case NodeType::StartArray:
- itsWriter.StartArray();
- case NodeType::InArray:
- itsWriter.EndArray();
- break;
- case NodeType::StartObject:
- itsWriter.StartObject();
- case NodeType::InObject:
- itsWriter.EndObject();
- break;
- }
-
- itsNodeStack.pop();
- itsNameCounter.pop();
- }
-
- //! Sets the name for the next node created with startNode
- void setNextName( const char * name )
- {
- itsNextName = name;
- }
-
- //! Saves a null to the current node, added by Intel
- void saveValue() { itsWriter.Null_(); }
- //! Saves a bool to the current node
- void saveValue(bool b) { itsWriter.Bool_(b); }
- //! Saves an int to the current node
- void saveValue(int i) { itsWriter.Int(i); }
- //! Saves a uint to the current node
- void saveValue(unsigned u) { itsWriter.Uint(u); }
- //! Saves an int64 to the current node
- void saveValue(int64_t i64) { itsWriter.Int64(i64); }
- //! Saves a uint64 to the current node
- void saveValue(uint64_t u64) { itsWriter.Uint64(u64); }
- //! Saves a double to the current node
- void saveValue(double d) { itsWriter.Double(d); }
- //! Saves a string to the current node
- void saveValue(std::string const & s) { itsWriter.String(s.c_str(), static_cast<rapidjson::SizeType>( s.size() )); }
- //! Saves a const char * to the current node
- void saveValue(char const * s) { itsWriter.String(s); }
-
- public:
-#ifdef _MSC_VER
- //! MSVC only long overload to current node
- void saveValue( unsigned long lu ){ saveLong( lu ); };
-#else // _MSC_VER
- //! Serialize a long if it would not be caught otherwise
- template <class T> inline
- typename std::enable_if<std::is_same<T, long>::value &&
- !std::is_same<T, std::int32_t>::value &&
- !std::is_same<T, std::int64_t>::value, void>::type
- saveValue( T t )
- {
- saveLong( t );
- return t;
- }
-
- //! Serialize an unsigned long if it would not be caught otherwise
- template <class T> inline
- typename std::enable_if<std::is_same<T, unsigned long>::value &&
- !std::is_same<T, std::uint32_t>::value &&
- !std::is_same<T, std::uint64_t>::value, void>::type
- saveValue( T t )
- {
- saveLong( t );
- return t;
- }
-#endif // _MSC_VER
-
- //! Save exotic arithmetic as strings to current node
- /*! Handles long long (if distinct from other types), unsigned long (if distinct), and long double */
- template<class T> inline
- typename std::enable_if<std::is_arithmetic<T>::value &&
- !std::is_same<T, long>::value &&
- !std::is_same<T, unsigned long>::value &&
- !std::is_same<T, std::int64_t>::value &&
- !std::is_same<T, std::uint64_t>::value &&
- (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long)), void>::type
- saveValue(T const & t)
- {
- std::stringstream ss; ss.precision( std::numeric_limits<long double>::max_digits10 );
- ss << t;
- saveValue( ss.str() );
- return t;
- }
-
- //! Write the name of the upcoming node and prepare object/array state
- /*! Since writeName is called for every value that is output, regardless of
- whether it has a name or not, it is the place where we will do a deferred
- check of our node state and decide whether we are in an array or an object.
-
- The general workflow of saving to the JSON archive is:
-
- 1. (optional) Set the name for the next node to be created, usually done by an NVP
- 2. Start the node
- 3. (if there is data to save) Write the name of the node (this function)
- 4. (if there is data to save) Save the data (with saveValue)
- 5. Finish the node
- */
- void writeName()
- {
- NodeType const & nodeType = itsNodeStack.top();
-
- // Start up either an object or an array, depending on state
- if(nodeType == NodeType::StartArray)
- {
- itsWriter.StartArray();
- itsNodeStack.top() = NodeType::InArray;
- }
- else if(nodeType == NodeType::StartObject)
- {
- itsNodeStack.top() = NodeType::InObject;
- itsWriter.StartObject();
- }
-
- // Array types do not output names
- if(nodeType == NodeType::InArray) return;
-
- if(itsNextName == nullptr)
- {
- std::string name = "value" + std::to_string( itsNameCounter.top()++ ) + "\0";
- saveValue(name);
- }
- else
- {
- saveValue(itsNextName);
- itsNextName = nullptr;
- }
- }
-
- //! Designates that the current node should be output as an array, not an object
- void makeArray()
- {
- itsNodeStack.top() = NodeType::StartArray;
- }
-
- //! @}
-
- private:
- WriteStream itsWriteStream; //!< Rapidjson write stream
- JSONWriter itsWriter; //!< Rapidjson writer
- char const * itsNextName; //!< The next name
- std::stack<uint32_t> itsNameCounter; //!< Counter for creating unique names for unnamed nodes
- std::stack<NodeType> itsNodeStack;
- }; // JSONOutputArchive
-
- // ######################################################################
- //! An input archive designed to load data from JSON
- /*! This archive uses RapidJSON to read in a JSON archive.
-
- Input JSON should have been produced by the JSONOutputArchive. Data can
- only be added to dynamically sized containers (marked by JSON arrays) -
- the input archive will determine their size by looking at the number of child nodes.
- Only JSON originating from a JSONOutputArchive is officially supported, but data
- from other sources may work if properly formatted.
-
- The JSONInputArchive does not require that nodes are loaded in the same
- order they were saved by JSONOutputArchive. Using name value pairs (NVPs),
- it is possible to load in an out of order fashion or otherwise skip/select
- specific nodes to load.
-
- The default behavior of the input archive is to read sequentially starting
- with the first node and exploring its children. When a given NVP does
- not match the read in name for a node, the archive will search for that
- node at the current level and load it if it exists. After loading an out of
- order node, the archive will then proceed back to loading sequentially from
- its new position.
-
- Consider this simple example where loading of some data is skipped:
-
- @code{cpp}
- // imagine the input file has someData(1-9) saved in order at the top level node
- ar( someData1, someData2, someData3 ); // XML loads in the order it sees in the file
- ar( cereal::make_nvp( "hello", someData6 ) ); // NVP given does not
- // match expected NVP name, so we search
- // for the given NVP and load that value
- ar( someData7, someData8, someData9 ); // with no NVP given, loading resumes at its
- // current location, proceeding sequentially
- @endcode
-
- \ingroup Archives */
- class JSONInputArchive : public InputArchive<JSONInputArchive>
- {
- private:
- typedef rapidjson::GenericReadStream ReadStream;
- typedef rapidjson::GenericValue<rapidjson::UTF8<>> JSONValue;
- typedef JSONValue::ConstMemberIterator MemberIterator;
- typedef JSONValue::ConstValueIterator ValueIterator;
- typedef rapidjson::Document::GenericValue GenericValue;
-
- public:
- /*! @name Common Functionality
- Common use cases for directly interacting with an JSONInputArchive */
- //! @{
-
- //! Construct, reading from the provided stream
- /*! @param stream The stream to read from */
- JSONInputArchive(std::istream & stream) :
- InputArchive<JSONInputArchive>(this),
- itsNextName( nullptr ),
- itsReadStream(stream)
- {
- itsDocument.ParseStream<0>(itsReadStream);
- itsIteratorStack.emplace_back(itsDocument.MemberBegin(), itsDocument.MemberEnd());
- }
-
- //! Loads some binary data, encoded as a base64 string
- /*! This will automatically start and finish a node to load the data, and can be called directly by
- users.
-
- Note that this follows the same ordering rules specified in the class description in regards
- to loading in/out of order */
- void loadBinaryValue( void * data, size_t size, const char * name = nullptr )
- {
- itsNextName = name;
-
- std::string encoded;
- loadValue( encoded );
- auto decoded = base64::decode( encoded );
-
- if( size != decoded.size() )
- throw Exception("Decoded binary data size does not match specified size");
-
- std::memcpy( data, decoded.data(), decoded.size() );
- itsNextName = nullptr;
- };
-
- // Intel Added this as a custom parsing hook for the AttributeValue map
- void loadAttributeValues(std::map<std::string, OC::AttributeValue>& map);
-
- private:
- //! @}
- /*! @name Internal Functionality
- Functionality designed for use by those requiring control over the inner mechanisms of
- the JSONInputArchive */
- //! @{
-
- //! An internal iterator that handles both array and object types
- /*! This class is a variant and holds both types of iterators that
- rapidJSON supports - one for arrays and one for objects. */
- class Iterator
- {
- public:
- friend class cereal::JSONInputArchive;
- Iterator() : itsIndex( 0 ), itsType(Null_) {}
-
- Iterator(MemberIterator begin, MemberIterator end) :
- itsMemberItBegin(begin), itsMemberItEnd(end), itsIndex(0), itsType(Member)
- { }
-
- Iterator(ValueIterator begin, ValueIterator end) :
- itsValueItBegin(begin), itsValueItEnd(end), itsIndex(0), itsType(Value)
- { }
-
- //! Advance to the next node
- Iterator & operator++()
- {
- ++itsIndex;
- return *this;
- }
-
- //! Get the value of the current node
- GenericValue const & value()
- {
- switch(itsType)
- {
- case Value : return itsValueItBegin[itsIndex];
- case Member: return itsMemberItBegin[itsIndex].value;
- default: throw cereal::Exception("Invalid Iterator Type!");
- }
- }
-
- //! Get the name of the current node, or nullptr if it has no name
- const char * name() const
- {
- if( itsType == Member && (itsMemberItBegin + itsIndex) != itsMemberItEnd )
- return itsMemberItBegin[itsIndex].name.GetString();
- else
- return nullptr;
- }
-
- //! Adjust our position such that we are at the node with the given name
- /*! @throws Exception if no such named node exists */
- inline void search( const char * searchName )
- {
- const auto len = std::strlen( searchName );
- size_t index = 0;
- for( auto it = itsMemberItBegin; it != itsMemberItEnd; ++it, ++index )
- if( std::strncmp( searchName, it->name.GetString(), len ) == 0 )
- {
- itsIndex = index;
- return;
- }
-
- throw Exception("JSON Parsing failed - provided NVP not found");
- }
-
- private:
- MemberIterator itsMemberItBegin, itsMemberItEnd; //!< The member iterator (object)
- ValueIterator itsValueItBegin, itsValueItEnd; //!< The value iterator (array)
- size_t itsIndex; //!< The current index of this iterator
- enum Type {Value, Member, Null_} itsType; //!< Whether this holds values (array) or members (objects) or nothing
- };
-
- //! Searches for the expectedName node if it doesn't match the actualName
- /*! This needs to be called before every load or node start occurs. This function will
- check to see if an NVP has been provided (with setNextName) and if so, see if that name matches the actual
- next name given. If the names do not match, it will search in the current level of the JSON for that name.
- If the name is not found, an exception will be thrown.
-
- Resets the NVP name after called.
-
- @throws Exception if an expectedName is given and not found */
- inline void search()
- {
- // The name an NVP provided with setNextName()
- if( itsNextName )
- {
- // The actual name of the current node
- auto const actualName = itsIteratorStack.back().name();
-
- // Do a search if we don't see a name coming up, or if the names don't match
- if( !actualName || std::strcmp( itsNextName, actualName ) != 0 )
- itsIteratorStack.back().search( itsNextName );
- }
-
- itsNextName = nullptr;
- }
-
- public:
- //! Starts a new node, going into its proper iterator
- /*! This places an iterator for the next node to be parsed onto the iterator stack. If the next
- node is an array, this will be a value iterator, otherwise it will be a member iterator.
-
- By default our strategy is to start with the document root node and then recursively iterate through
- all children in the order they show up in the document.
- We don't need to know NVPs to do this; we'll just blindly load in the order things appear in.
-
- If we were given an NVP, we will search for it if it does not match our the name of the next node
- that would normally be loaded. This functionality is provided by search(). */
- void startNode()
- {
- search();
-
- if(itsIteratorStack.back().value().IsArray())
- itsIteratorStack.emplace_back(itsIteratorStack.back().value().Begin(), itsIteratorStack.back().value().End());
- else
- itsIteratorStack.emplace_back(itsIteratorStack.back().value().MemberBegin(), itsIteratorStack.back().value().MemberEnd());
- }
-
- //! Finishes the most recently started node
- void finishNode()
- {
- itsIteratorStack.pop_back();
- ++itsIteratorStack.back();
- }
-
- //! Sets the name for the next node created with startNode
- void setNextName( const char * name )
- {
- itsNextName = name;
- }
-
- //! Loads a value from the current node - small signed overload
- template<class T> inline
- typename std::enable_if<std::is_signed<T>::value && sizeof(T) < sizeof(int64_t), void>::type
- loadValue(T & val)
- {
- search();
-
- val = itsIteratorStack.back().value().GetInt();
- ++itsIteratorStack.back();
- }
-
- //! Loads a value from the current node - small unsigned overload
- template<class T> inline
- typename std::enable_if<(std::is_unsigned<T>::value && sizeof(T) < sizeof(uint64_t)) &&
- !std::is_same<bool, T>::value, void>::type
- loadValue(T & val)
- {
- search();
-
- val = itsIteratorStack.back().value().GetUint();
- ++itsIteratorStack.back();
- }
-
- //! Loads a value from the current node - bool overload
- void loadValue(bool & val) { search(); val = itsIteratorStack.back().value().GetBool_(); ++itsIteratorStack.back(); }
- //! Loads a value from the current node - int64 overload
- void loadValue(int64_t & val) { search(); val = itsIteratorStack.back().value().GetInt64(); ++itsIteratorStack.back(); }
- //! Loads a value from the current node - uint64 overload
- void loadValue(uint64_t & val) { search(); val = itsIteratorStack.back().value().GetUint64(); ++itsIteratorStack.back(); }
- //! Loads a value from the current node - float overload
- void loadValue(float & val) { search(); val = static_cast<float>(itsIteratorStack.back().value().GetDouble()); ++itsIteratorStack.back(); }
- //! Loads a value from the current node - double overload
- void loadValue(double & val) { search(); val = itsIteratorStack.back().value().GetDouble(); ++itsIteratorStack.back(); }
- //! Loads a value from the current node - string overload
- void loadValue(std::string & val) { search(); val = itsIteratorStack.back().value().GetString(); ++itsIteratorStack.back(); }
-
- private:
- //! Convert a string to a long long
- void stringToNumber( std::string const & str, long long & val ) { val = std::stoll( str ); }
- //! Convert a string to an unsigned long long
- void stringToNumber( std::string const & str, unsigned long long & val ) { val = std::stoull( str ); }
- //! Convert a string to a long double
- void stringToNumber( std::string const & str, long double & val ) { val = std::stold( str ); }
-
- public:
- //! Loads a value from the current node - long double and long long overloads
- template<class T> inline
- typename std::enable_if<std::is_arithmetic<T>::value &&
- !std::is_same<T, long>::value &&
- !std::is_same<T, unsigned long>::value &&
- !std::is_same<T, std::int64_t>::value &&
- !std::is_same<T, std::uint64_t>::value &&
- (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long)), void>::type
- loadValue(T & val)
- {
- std::string encoded;
- loadValue( encoded );
- stringToNumber( encoded, val );
- }
-
- //! Loads the size for a SizeTag
- void loadSize(size_type & size)
- {
- size = (itsIteratorStack.rbegin() + 1)->value().Size();
- }
-
- //! @}
-
- private:
- const char * itsNextName; //!< Next name set by NVP
- ReadStream itsReadStream; //!< Rapidjson write stream
- std::vector<Iterator> itsIteratorStack; //!< 'Stack' of rapidJSON iterators
- rapidjson::Document itsDocument; //!< Rapidjson document
- };
-
- // ######################################################################
- // JSONArchive prologue and epilogue functions
- // ######################################################################
-
- // ######################################################################
- //! Prologue for NVPs for JSON archives
- /*! NVPs do not start or finish nodes - they just set up the names */
- template <class T> inline
- void prologue( JSONOutputArchive &, NameValuePair<T> const & )
- { }
-
- //! Prologue for NVPs for JSON archives
- template <class T> inline
- void prologue( JSONInputArchive &, NameValuePair<T> const & )
- { }
-
- // ######################################################################
- //! Epilogue for NVPs for JSON archives
- /*! NVPs do not start or finish nodes - they just set up the names */
- template <class T> inline
- void epilogue( JSONOutputArchive &, NameValuePair<T> const & )
- { }
-
- //! Epilogue for NVPs for JSON archives
- /*! NVPs do not start or finish nodes - they just set up the names */
- template <class T> inline
- void epilogue( JSONInputArchive &, NameValuePair<T> const & )
- { }
-
- // ######################################################################
- //! Prologue for SizeTags for JSON archives
- /*! SizeTags are strictly ignored for JSON, they just indicate
- that the current node should be made into an array */
- template <class T> inline
- void prologue( JSONOutputArchive & ar, SizeTag<T> const & )
- {
- ar.makeArray();
- }
-
- //! Prologue for SizeTags for JSON archives
- template <class T> inline
- void prologue( JSONInputArchive &, SizeTag<T> const & )
- { }
-
- // ######################################################################
- //! Epilogue for SizeTags for JSON archives
- /*! SizeTags are strictly ignored for JSON */
- template <class T> inline
- void epilogue( JSONOutputArchive &, SizeTag<T> const & )
- { }
-
- //! Epilogue for SizeTags for JSON archives
- template <class T> inline
- void epilogue( JSONInputArchive &, SizeTag<T> const & )
- { }
-
- // ######################################################################
- //! Prologue for all other types for JSON archives (except minimal types)
- /*! Starts a new node, named either automatically or by some NVP,
- that may be given data by the type about to be archived
-
- Minimal types do not start or finish nodes */
- template <class T> inline
- typename std::enable_if<!std::is_arithmetic<T>::value &&
- !traits::has_minimal_output_serialization<T, JSONOutputArchive>::value, void>::type
- prologue( JSONOutputArchive & ar, T const & )
- {
- ar.startNode();
- }
-
- //! Prologue for all other types for JSON archives
- template <class T> inline
- typename std::enable_if<!std::is_arithmetic<T>::value &&
- !traits::has_minimal_input_serialization<T, JSONOutputArchive>::value, void>::type
- prologue( JSONInputArchive & ar, T const & )
- {
- ar.startNode();
- }
-
- // ######################################################################
- //! Epilogue for all other types other for JSON archives (except minimal types
- /*! Finishes the node created in the prologue
-
- Minimal types do not start or finish nodes */
- template <class T> inline
- typename std::enable_if<!std::is_arithmetic<T>::value &&
- !traits::has_minimal_output_serialization<T, JSONOutputArchive>::value, void>::type
- epilogue( JSONOutputArchive & ar, T const & )
- {
- ar.finishNode();
- }
-
- //! Epilogue for all other types other for JSON archives
- template <class T> inline
- typename std::enable_if<!std::is_arithmetic<T>::value &&
- !traits::has_minimal_input_serialization<T, JSONOutputArchive>::value, void>::type
- epilogue( JSONInputArchive & ar, T const & )
- {
- ar.finishNode();
- }
-
- // ######################################################################
- //! Prologue for arithmetic types for JSON archives
- template <class T> inline
- typename std::enable_if<std::is_arithmetic<T>::value, void>::type
- prologue( JSONOutputArchive & ar, T const & )
- {
- ar.writeName();
- }
-
- //! Prologue for arithmetic types for JSON archives
- template <class T> inline
- typename std::enable_if<std::is_arithmetic<T>::value, void>::type
- prologue( JSONInputArchive &, T const & )
- { }
-
- // ######################################################################
- //! Epilogue for arithmetic types for JSON archives
- template <class T> inline
- typename std::enable_if<std::is_arithmetic<T>::value, void>::type
- epilogue( JSONOutputArchive &, T const & )
- { }
-
- //! Epilogue for arithmetic types for JSON archives
- template <class T> inline
- typename std::enable_if<std::is_arithmetic<T>::value, void>::type
- epilogue( JSONInputArchive &, T const & )
- { }
-
- // ######################################################################
- //! Prologue for strings for JSON archives
- template<class CharT, class Traits, class Alloc> inline
- void prologue(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const &)
- {
- ar.writeName();
- }
-
- //! Prologue for strings for JSON archives
- template<class CharT, class Traits, class Alloc> inline
- void prologue(JSONInputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
- { }
-
- // ######################################################################
- //! Epilogue for strings for JSON archives
- template<class CharT, class Traits, class Alloc> inline
- void epilogue(JSONOutputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
- { }
-
- //! Epilogue for strings for JSON archives
- template<class CharT, class Traits, class Alloc> inline
- void epilogue(JSONInputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
- { }
-
- // ######################################################################
- // Common JSONArchive serialization functions
- // ######################################################################
-
- //! Serializing NVP types to JSON
- template <class T> inline
- void save( JSONOutputArchive & ar, NameValuePair<T> const & t )
- {
- ar.setNextName( t.name );
- ar( t.value );
- }
-
- template <class T> inline
- void load( JSONInputArchive & ar, NameValuePair<T> & t )
- {
- ar.setNextName( t.name );
- ar( t.value );
- }
-
- //! Saving for arithmetic to JSON
- template<class T> inline
- typename std::enable_if<std::is_arithmetic<T>::value, void>::type
- save(JSONOutputArchive & ar, T const & t)
- {
- ar.saveValue( t );
- }
-
- //! Loading arithmetic from JSON
- template<class T> inline
- typename std::enable_if<std::is_arithmetic<T>::value, void>::type
- load(JSONInputArchive & ar, T & t)
- {
- ar.loadValue( t );
- }
-
- //! saving string to JSON
- template<class CharT, class Traits, class Alloc> inline
- void save(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
- {
- ar.saveValue( str );
- }
-
- //! loading string from JSON
- template<class CharT, class Traits, class Alloc> inline
- void load(JSONInputArchive & ar, std::basic_string<CharT, Traits, Alloc> & str)
- {
- ar.loadValue( str );
- }
-
- // ######################################################################
- //! Saving SizeTags to JSON
- template <class T> inline
- void save( JSONOutputArchive &, SizeTag<T> const & )
- {
- // nothing to do here, we don't explicitly save the size
- }
-
- //! Loading SizeTags from JSON
- template <class T> inline
- void load( JSONInputArchive & ar, SizeTag<T> & st )
- {
- ar.loadSize( st.size );
- }
-} // namespace cereal
-
-// register archives for polymorphic support
-CEREAL_REGISTER_ARCHIVE(cereal::JSONInputArchive)
-CEREAL_REGISTER_ARCHIVE(cereal::JSONOutputArchive)
-
-#endif // CEREAL_ARCHIVES_JSON_HPP_
+++ /dev/null
-From 17300ee96e42f8848d27db6fc97f04de293662d8 Mon Sep 17 00:00:00 2001
-From: Erich Keane <erich.keane@intel.com>
-Date: Thu, 6 Nov 2014 14:37:00 -0800
-Subject: [PATCH] Get this to work on g++4.6.3
-
----
- include/cereal/cereal.hpp | 2 +-
- include/cereal/details/helpers.hpp | 32 ++++++++--------
- include/cereal/details/traits.hpp | 61 +++++++++++++++++-------------
- include/cereal/external/rapidjson/reader.h | 13 ++-----
- include/cereal/external/rapidjson/writer.h | 12 ++----
- include/cereal/types/common.hpp | 19 +++++++---
- include/cereal/types/memory.hpp | 10 ++---
- 7 files changed, 77 insertions(+), 72 deletions(-)
-
-diff --git a/include/cereal/cereal.hpp b/include/cereal/cereal.hpp
-index b2858af..a219729 100644
---- a/include/cereal/cereal.hpp
-+++ b/include/cereal/cereal.hpp
-@@ -856,7 +856,7 @@ namespace cereal
- std::uint32_t version;
-
- process( make_nvp<ArchiveType>("cereal_class_version", version) );
-- itsVersionedTypes.emplace_hint( lookupResult, hash, version );
-+ itsVersionedTypes.insert( lookupResult, std::pair<std::size_t, std::uint32_t>(hash, version) );
-
- return version;
- }
-diff --git a/include/cereal/details/helpers.hpp b/include/cereal/details/helpers.hpp
-index e792d44..60e13c8 100644
---- a/include/cereal/details/helpers.hpp
-+++ b/include/cereal/details/helpers.hpp
-@@ -55,7 +55,7 @@ namespace cereal
- /*! To ensure compatability between 32, 64, etc bit machines, we need to use
- * a fixed size type instead of size_t, which may vary from machine to
- * machine. */
-- using size_type = uint64_t;
-+ typedef uint64_t size_type;
-
- // forward decls
- class BinaryOutputArchive;
-@@ -138,12 +138,12 @@ namespace cereal
- // otherwise, we store a reference. If we were passed an array, don't
- // decay the type - keep it as an array, and then proceed as normal
- // with the RValue business
-- using DT = typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
-+ typedef typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
- typename std::remove_cv<T>::type,
-- typename std::decay<T>::type>::type;
-- using Type = typename std::conditional<std::is_rvalue_reference<T>::value,
-+ typename std::decay<T>::type>::type DT;
-+ typedef typename std::conditional<std::is_rvalue_reference<T>::value,
- DT,
-- typename std::add_lvalue_reference<DT>::type>::type;
-+ typename std::add_lvalue_reference<DT>::type>::type Type;
- // prevent nested nvps
- static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
- "Cannot pair a name to a NameValuePair" );
-@@ -207,9 +207,9 @@ namespace cereal
- {
- //! Internally store the pointer as a void *, keeping const if created with
- //! a const pointer
-- using PT = typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
-+ typedef typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
- const void *,
-- void *>::type;
-+ void *>::type PT;
-
- BinaryData( T && d, uint64_t s ) : data(d), size(s) {}
-
-@@ -248,10 +248,10 @@ namespace cereal
- private:
- // If we get passed an RValue, we'll just make a local copy if it here
- // otherwise, we store a reference
-- using DT = typename std::decay<T>::type;
-- using Type = typename std::conditional<std::is_rvalue_reference<T>::value,
-+ typedef typename std::decay<T>::type DT;
-+ typedef typename std::conditional<std::is_rvalue_reference<T>::value,
- DT,
-- typename std::add_lvalue_reference<DT>::type>::type;
-+ typename std::add_lvalue_reference<DT>::type>::type Type;
-
- public:
- SizeTag( T && sz ) : size(const_cast<Type>(sz)) {}
-@@ -283,17 +283,17 @@ namespace cereal
- template <class Key, class Value>
- struct MapItem
- {
-- using DecayKey = typename std::decay<Key>::type;
-- using KeyType = typename std::conditional<
-+ typedef typename std::decay<Key>::type DecayKey;
-+ typedef typename std::conditional<
- std::is_rvalue_reference<Key>::value,
- DecayKey,
-- typename std::add_lvalue_reference<DecayKey>::type>::type;
-+ typename std::add_lvalue_reference<DecayKey>::type>::type KeyType;
-
-- using DecayValue = typename std::decay<Value>::type;
-- using ValueType = typename std::conditional<
-+ typedef typename std::decay<Value>::type DecayValue;
-+ typedef typename std::conditional<
- std::is_rvalue_reference<Value>::value,
- DecayValue,
-- typename std::add_lvalue_reference<DecayValue>::type>::type;
-+ typename std::add_lvalue_reference<DecayValue>::type>::type ValueType;
-
- //! Construct a MapItem from a key and a value
- /*! @internal */
-diff --git a/include/cereal/details/traits.hpp b/include/cereal/details/traits.hpp
-index 871886f..011054b 100644
---- a/include/cereal/details/traits.hpp
-+++ b/include/cereal/details/traits.hpp
-@@ -411,12 +411,12 @@ namespace cereal
- };
-
- template <class T, class A, bool Valid>
-- struct get_member_save_minimal_type { using type = void; };
-+ struct get_member_save_minimal_type { typedef void type; };
-
- template <class T, class A>
- struct get_member_save_minimal_type<T, A, true>
- {
-- using type = decltype( cereal::access::member_save_minimal( std::declval<A const &>(), std::declval<T const &>() ) );
-+ typedef decltype( cereal::access::member_save_minimal( std::declval<A const &>(), std::declval<T const &>() ) ) type;
- };
- } // end namespace detail
-
-@@ -428,7 +428,7 @@ namespace cereal
- "cereal detected a non-const member save_minimal. "
- "save_minimal member functions must always be const" );
-
-- using type = typename detail::get_member_save_minimal_type<T, A, check::value>::type;
-+ typedef typename detail::get_member_save_minimal_type<T, A, check::value>::type type;
- static_assert( (check::value && is_minimal_type<type>::value) || !check::value,
- "cereal detected a member save_minimal with an invalid return type. "
- "return type must be arithmetic or string" );
-@@ -473,12 +473,12 @@ namespace cereal
- };
-
- template <class T, class A, bool Valid>
-- struct get_member_versioned_save_minimal_type { using type = void; };
-+ struct get_member_versioned_save_minimal_type { typedef void type; };
-
- template <class T, class A>
- struct get_member_versioned_save_minimal_type<T, A, true>
- {
-- using type = decltype( cereal::access::member_save_minimal( std::declval<A const &>(), std::declval<T const &>(), 0 ) );
-+ typedef decltype( cereal::access::member_save_minimal( std::declval<A const &>(), std::declval<T const &>(), 0 ) ) type;
- };
- } // end namespace detail
-
-@@ -490,7 +490,7 @@ namespace cereal
- "cereal detected a versioned non-const member save_minimal. "
- "save_minimal member functions must always be const" );
-
-- using type = typename detail::get_member_versioned_save_minimal_type<T, A, check::value>::type;
-+ typedef typename detail::get_member_versioned_save_minimal_type<T, A, check::value>::type type;
- static_assert( (check::value && is_minimal_type<type>::value) || !check::value,
- "cereal detected a versioned member save_minimal with an invalid return type. "
- "return type must be arithmetic or string" );
-@@ -519,12 +519,12 @@ namespace cereal
- };
-
- template <class T, class A, bool Valid>
-- struct get_non_member_save_minimal_type { using type = void; };
-+ struct get_non_member_save_minimal_type { typedef void type; };
-
- template <class T, class A>
- struct get_non_member_save_minimal_type <T, A, true>
- {
-- using type = decltype( save_minimal( std::declval<A const &>(), std::declval<T const &>() ) );
-+ typedef decltype( save_minimal( std::declval<A const &>(), std::declval<T const &>() ) ) type;
- };
- } // end namespace detail
-
-@@ -536,7 +536,7 @@ namespace cereal
- "cereal detected a non-const type parameter in non-member save_minimal. "
- "save_minimal non-member functions must always pass their types as const" );
-
-- using type = typename detail::get_non_member_save_minimal_type<T, A, check::value>::type;
-+ typedef typename detail::get_non_member_save_minimal_type<T, A, check::value>::type type;
- static_assert( (check::value && is_minimal_type<type>::value) || !check::value,
- "cereal detected a non-member save_minimal with an invalid return type. "
- "return type must be arithmetic or string" );
-@@ -565,12 +565,12 @@ namespace cereal
- };
-
- template <class T, class A, bool Valid>
-- struct get_non_member_versioned_save_minimal_type { using type = void; };
-+ struct get_non_member_versioned_save_minimal_type { typedef void type; };
-
- template <class T, class A>
- struct get_non_member_versioned_save_minimal_type <T, A, true>
- {
-- using type = decltype( save_minimal( std::declval<A const &>(), std::declval<T const &>(), 0 ) );
-+ typedef decltype( save_minimal( std::declval<A const &>(), std::declval<T const &>(), 0 ) ) type;
- };
- } // end namespace detail
-
-@@ -582,7 +582,7 @@ namespace cereal
- "cereal detected a non-const type parameter in versioned non-member save_minimal. "
- "save_minimal non-member functions must always pass their types as const" );
-
-- using type = typename detail::get_non_member_versioned_save_minimal_type<T, A, check::value>::type;
-+ typedef typename detail::get_non_member_versioned_save_minimal_type<T, A, check::value>::type type;
- static_assert( (check::value && is_minimal_type<type>::value) || !check::value,
- "cereal detected a non-member versioned save_minimal with an invalid return type. "
- "return type must be arithmetic or string" );
-@@ -608,7 +608,7 @@ namespace cereal
- template <class Source>
- struct NoConvertConstRef : NoConvertBase
- {
-- using type = Source; //!< Used to get underlying type easily
-+ typedef Source type; //!< Used to get underlying type easily
-
- template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
- operator Dest () = delete;
-@@ -626,7 +626,7 @@ namespace cereal
- template <class Source>
- struct NoConvertRef : NoConvertBase
- {
-- using type = Source; //!< Used to get underlying type easily
-+ typedef Source type; //!< Used to get underlying type easily
-
- template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
- operator Dest () = delete;
-@@ -698,7 +698,7 @@ namespace cereal
- "cereal detected member load_minimal but no valid member save_minimal. "
- "cannot evaluate correctness of load_minimal without valid save_minimal." );
-
-- using SaveType = typename detail::get_member_save_minimal_type<T, A, true>::type;
-+ typedef typename detail::get_member_save_minimal_type<T, A, true>::type SaveType;
- const static bool value = has_member_load_minimal_impl<T, A>::value;
- const static bool valid = has_member_load_minimal_type_impl<T, A, SaveType>::value;
-
-@@ -759,7 +759,7 @@ namespace cereal
- "cereal detected member versioned load_minimal but no valid member versioned save_minimal. "
- "cannot evaluate correctness of load_minimal without valid save_minimal." );
-
-- using SaveType = typename detail::get_member_versioned_save_minimal_type<T, A, true>::type;
-+ typedef typename detail::get_member_versioned_save_minimal_type<T, A, true>::type SaveType;
- const static bool value = has_member_versioned_load_minimal_impl<T, A>::value;
- const static bool valid = has_member_versioned_load_minimal_type_impl<T, A, SaveType>::value;
-
-@@ -814,8 +814,8 @@ namespace cereal
- "cereal detected non-member load_minimal but no valid non-member save_minimal. "
- "cannot evaluate correctness of load_minimal without valid save_minimal." );
-
-- using SaveType = typename detail::get_non_member_save_minimal_type<T, A, true>::type;
-- using check = has_non_member_load_minimal_impl<T, A, SaveType>;
-+ typedef typename detail::get_non_member_save_minimal_type<T, A, true>::type SaveType;
-+ typedef has_non_member_load_minimal_impl<T, A, SaveType> check;
- static const bool value = check::exists;
-
- static_assert( check::valid || !check::exists, "cereal detected different types in corresponding non-member load_minimal and save_minimal functions. "
-@@ -866,8 +866,8 @@ namespace cereal
- "cereal detected non-member versioned load_minimal but no valid non-member versioned save_minimal. "
- "cannot evaluate correctness of load_minimal without valid save_minimal." );
-
-- using SaveType = typename detail::get_non_member_versioned_save_minimal_type<T, A, true>::type;
-- using check = has_non_member_versioned_load_minimal_impl<T, A, SaveType>;
-+ typedef typename detail::get_non_member_versioned_save_minimal_type<T, A, true>::type SaveType;
-+ typedef has_non_member_versioned_load_minimal_impl<T, A, SaveType> check;;
- static const bool value = check::exists;
-
- static_assert( check::valid || !check::exists, "cereal detected different types in corresponding non-member versioned load_minimal and save_minimal functions. "
-@@ -1182,9 +1182,16 @@ namespace cereal
- };
- }
-
-+ // works around the lack of decltype inheritance in GCC 4.6
-+ template<class T>
-+ struct shared_wrapper
-+ {
-+ typedef decltype(detail::shared_from_this_wrapper::check(std::declval<T>())) type;
-+
-+ };
- //! Determine if T or any base class of T has inherited from std::enable_shared_from_this
- template<class T>
-- struct has_shared_from_this : decltype(detail::shared_from_this_wrapper::check(std::declval<T>()))
-+ struct has_shared_from_this : shared_wrapper<T>::type
- { };
-
- //! Get the type of the base class of T which inherited from std::enable_shared_from_this
-@@ -1192,10 +1199,10 @@ namespace cereal
- struct get_shared_from_this_base
- {
- private:
-- using PtrType = decltype(detail::shared_from_this_wrapper::get(std::declval<T>()));
-+ typedef decltype(detail::shared_from_this_wrapper::get(std::declval<T>())) PtrType;
- public:
- //! The type of the base of T that inherited from std::enable_shared_from_this
-- using type = typename std::decay<typename PtrType::element_type>::type;
-+ typedef typename std::decay<typename PtrType::element_type>::type type;
- };
-
- // ######################################################################
-@@ -1209,14 +1216,14 @@ namespace cereal
- template <class T, bool IsCerealMinimalTrait = std::is_base_of<detail::NoConvertBase, T>::value>
- struct strip_minimal
- {
-- using type = T;
-+ typedef T type;
- };
-
- //! Specialization for types wrapped in a NoConvert
- template <class T>
- struct strip_minimal<T, true>
- {
-- using type = typename T::type;
-+ typedef typename T::type type;
- };
- } // namespace traits
-
-@@ -1232,10 +1239,12 @@ namespace cereal
- { return nullptr; }
- };
-
-+ template<class T>
-+ struct is_default_constructible : std::is_constructible<T>{};
- template <class T, class A>
- struct Construct<T, A, false, false>
- {
-- static_assert( std::is_default_constructible<T>::value,
-+ static_assert( is_default_constructible<T>::value,
- "Trying to serialize a an object with no default constructor. \n\n "
- "Types must either be default constructible or define either a member or non member Construct function. \n "
- "Construct functions generally have the signature: \n\n "
-diff --git a/include/cereal/external/rapidjson/reader.h b/include/cereal/external/rapidjson/reader.h
-index 7790907..3ee838c 100644
---- a/include/cereal/external/rapidjson/reader.h
-+++ b/include/cereal/external/rapidjson/reader.h
-@@ -402,20 +402,13 @@ private:
- }
-
- // cereal Temporary until constexpr support is added in RTM
--#ifdef _MSC_VER
-+//#ifdef _MSC_VER
- template <class Ch>
- bool characterOk( Ch c )
- {
- return c < 256;
- }
--
-- template <>
-- bool characterOk<char>( Ch )
-- {
-- return true;
-- }
--
--#else
-+/*#else
- // As part of a fix for GCC 4.7
- template <class T>
- static constexpr int to_int( T t ){ return t; }
-@@ -432,7 +425,7 @@ private:
- characterOk(Ch c)
- { return c < 256; }
- #endif
--
-+*/
- // Parse string, handling the prefix and suffix double quotes and escaping.
- template<unsigned parseFlags, typename Stream, typename Handler>
- void ParseString(Stream& stream, Handler& handler) {
-diff --git a/include/cereal/external/rapidjson/writer.h b/include/cereal/external/rapidjson/writer.h
-index 0f87255..e02c27a 100644
---- a/include/cereal/external/rapidjson/writer.h
-+++ b/include/cereal/external/rapidjson/writer.h
-@@ -177,20 +177,14 @@ protected:
- }
-
- // cereal Temporary until constexpr support is added in RTM
--#ifdef _MSC_VER
-+//#ifdef _MSC_VER
- template <class Ch>
- bool characterOk( Ch c )
- {
- return c < 256;
- }
-
-- template <>
-- bool characterOk<char>( Ch )
-- {
-- return true;
-- }
--
--#else
-+/*#else
- // As part of a fix for GCC 4.7
- template <class T>
- static constexpr int to_int( T t ){ return t; }
-@@ -206,7 +200,7 @@ protected:
- typename std::enable_if< to_int(std::numeric_limits<Ch>::max()) >= to_int(256), bool>::type
- characterOk(Ch c)
- { return c < 256; }
--#endif
-+#endif*/
-
- //! \todo Optimization with custom double-to-string converter.
- void WriteDouble(double d) {
-diff --git a/include/cereal/types/common.hpp b/include/cereal/types/common.hpp
-index abb8bfd..5c014cd 100644
---- a/include/cereal/types/common.hpp
-+++ b/include/cereal/types/common.hpp
-@@ -55,6 +55,15 @@ namespace cereal
-
- namespace
- {
-+ template<class en>
-+ struct underlying_type
-+ {
-+ typedef typename std::conditional<
-+ en(-1)<en(0),
-+ typename std::make_signed<en>::type,
-+ typename std::make_unsigned<en>::type
-+ > ::type type;
-+ };
- //! Gets the underlying type of an enum
- /*! @internal */
- template <class T, bool IsEnum>
-@@ -64,7 +73,7 @@ namespace cereal
- /*! Specialization for when we actually have an enum
- @internal */
- template <class T>
-- struct enum_underlying_type<T, true> { using type = typename std::underlying_type<T>::type; };
-+ struct enum_underlying_type<T, true> { typedef typename underlying_type<T>::type type; };
- } // anon namespace
-
- //! Checks if a type is an enum
-@@ -78,13 +87,13 @@ namespace cereal
- class is_enum
- {
- private:
-- using DecayedT = typename std::decay<T>::type;
-- using StrippedT = typename ::cereal::traits::strip_minimal<DecayedT>::type;
-+ typedef typename std::decay<T>::type DecayedT;
-+ typedef typename ::cereal::traits::strip_minimal<DecayedT>::type StrippedT;
-
- public:
- static const bool value = std::is_enum<StrippedT>::value;
-- using type = StrippedT;
-- using base_type = typename enum_underlying_type<StrippedT, value>::type;
-+ typedef StrippedT type;
-+ typedef typename enum_underlying_type<StrippedT, value>::type base_type;
- };
- }
-
-diff --git a/include/cereal/types/memory.hpp b/include/cereal/types/memory.hpp
-index bf56c92..d2357ff 100644
---- a/include/cereal/types/memory.hpp
-+++ b/include/cereal/types/memory.hpp
-@@ -115,9 +115,9 @@ namespace cereal
- class EnableSharedStateHelper
- {
- // typedefs for parent type and storage type
-- using BaseType = typename ::cereal::traits::get_shared_from_this_base<T>::type;
-- using ParentType = std::enable_shared_from_this<BaseType>;
-- using StorageType = typename std::aligned_storage<sizeof(ParentType)>::type;
-+ typedef typename ::cereal::traits::get_shared_from_this_base<T>::type BaseType;
-+ typedef std::enable_shared_from_this<BaseType> ParentType;
-+ typedef typename std::aligned_storage<sizeof(ParentType)>::type StorageType;
-
- public:
- //! Saves the state of some type inheriting from enable_shared_from_this
-@@ -257,7 +257,7 @@ namespace cereal
- {
- // Storage type for the pointer - since we can't default construct this type,
- // we'll allocate it using std::aligned_storage and use a custom deleter
-- using ST = typename std::aligned_storage<sizeof(T)>::type;
-+ typedef typename std::aligned_storage<sizeof(T)>::type ST;
-
- // Valid flag - set to true once construction finishes
- // This prevents us from calling the destructor on
-@@ -345,7 +345,7 @@ namespace cereal
- {
- // Storage type for the pointer - since we can't default construct this type,
- // we'll allocate it using std::aligned_storage
-- using ST = typename std::aligned_storage<sizeof(T)>::type;
-+ typedef typename std::aligned_storage<sizeof(T)>::type ST;
-
- // Allocate storage - note the ST type so that deleter is correct if
- // an exception is thrown before we are initialized
---
-1.9.3
-
#include "OCPlatform.h"
#include "OCResource.h"
+#include "ocpayload.h"
#include <OCSerialization.h>
using namespace std;
OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
{
- if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
- {
+ if(clientResponse->payload == nullptr ||
+ (
+ clientResponse->payload->type != PAYLOAD_TYPE_DEVICE &&
+ clientResponse->payload->type != PAYLOAD_TYPE_PLATFORM &&
+ clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION
+ )
+ )
+ {
+ //OCPayloadDestroy(clientResponse->payload);
return OCRepresentation();
}
MessageContainer oc;
- try
- {
- oc.setJSONRepresentation(clientResponse->resJSONPayload);
- }
- catch (cereal::RapidJSONException& ex)
- {
- oclog() <<"RapidJSON Exception in parseGetSetCallback: "<<ex.what() <<std::endl<<
- "Data was:"<< clientResponse->resJSONPayload<< ":" << std::flush;
- throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_INVALID_JSON);
- }
- catch (cereal::Exception& ex)
- {
- oclog() <<"Cereal Exception in parseGetSetCallback: "<<ex.what() <<std::endl<<
- "Data was:"<< clientResponse->resJSONPayload<< ":" << std::flush;
- throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_INVALID_JSON);
- }
+ oc.setPayload(clientResponse->payload);
+ //OCPayloadDestroy(clientResponse->payload);
std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
if(it == oc.representations().end())
return OC_STACK_KEEP_TRANSACTION;
}
+ if(!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
+ {
+ oclog() << "listenCallback(): clientResponse payload was null or the wrong type"
+ << std::flush;
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
auto clientWrapper = context->clientWrapper.lock();
if(!clientWrapper)
return OC_STACK_KEEP_TRANSACTION;
}
- std::stringstream requestStream;
- requestStream << clientResponse->resJSONPayload;
-
- try
- {
-
- ListenOCContainer container(clientWrapper, clientResponse->devAddr,
- requestStream);
- // loop to ensure valid construction of all resources
- for(auto resource : container.Resources())
- {
- std::thread exec(context->callback, resource);
- exec.detach();
- }
-
- }
- catch(const std::exception& e)
+ ListenOCContainer container(clientWrapper, clientResponse->devAddr,
+ reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
+ // loop to ensure valid construction of all resources
+ for(auto resource : container.Resources())
{
- oclog() << "listenCallback failed to parse a malformed message: "
- << e.what()
- << std::endl
- << clientResponse->resJSONPayload
- << std::endl
- << clientResponse->result
- << std::flush;
- return OC_STACK_KEEP_TRANSACTION;
+ std::thread exec(context->callback, resource);
+ exec.detach();
}
+
return OC_STACK_KEEP_TRANSACTION;
}
return ret;
}
- std::string InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
+ OCPayload* InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
{
MessageContainer ocInfo;
ocInfo.addRepresentation(rep);
- return ocInfo.getJSONRepresentation(OCInfoFormat::IncludeOC);
+ return reinterpret_cast<OCPayload*>(ocInfo.getPayload());
}
OCStackResult InProcClientWrapper::PostResourceRepresentation(
result = OCDoResource(nullptr, OC_REST_POST,
url.c_str(), &devAddr,
- assembleSetResourcePayload(rep).c_str(),
+ assembleSetResourcePayload(rep),
CT_DEFAULT,
static_cast<OCQualityOfService>(QoS),
&cbdata,
result = OCDoResource(&handle, OC_REST_PUT,
url.c_str(), &devAddr,
- assembleSetResourcePayload(rep).c_str(),
+ assembleSetResourcePayload(rep),
CT_DEFAULT,
static_cast<OCQualityOfService>(QoS),
&cbdata,
else if(OC_REST_PUT == entityHandlerRequest->method)
{
pRequest->setRequestType(OC::PlatformCommands::PUT);
- pRequest->setPayload(std::string(reinterpret_cast<const char*>
- (entityHandlerRequest->reqJSONPayload)));
+ pRequest->setPayload(entityHandlerRequest->payload);
}
else if(OC_REST_POST == entityHandlerRequest->method)
{
pRequest->setRequestType(OC::PlatformCommands::POST);
- pRequest->setPayload(std::string(reinterpret_cast<const char*>
- (entityHandlerRequest->reqJSONPayload)));
+ pRequest->setPayload(entityHandlerRequest->payload);
}
else if(OC_REST_DELETE == entityHandlerRequest->method)
{
else
{
OCEntityHandlerResponse response;
- std::string payLoad = pResponse->getPayload();
+// OCRepPayload* payLoad = pResponse->getPayload();
HeaderOptions serverHeaderOptions = pResponse->getHeaderOptions();
response.requestHandle = pResponse->getRequestHandle();
response.resourceHandle = pResponse->getResourceHandle();
response.ehResult = pResponse->getResponseResult();
- response.payload = static_cast<char*>(OICMalloc(payLoad.length() + 1));
- if(!response.payload)
- {
- result = OC_STACK_NO_MEMORY;
- throw OCException(OC::Exception::NO_MEMORY, OC_STACK_NO_MEMORY);
- }
+ response.payload = reinterpret_cast<OCPayload*>(pResponse->getPayload());
- payLoad.copy(response.payload, payLoad.length());
- response.payload[payLoad.length()] = '\0';
- response.payloadSize = payLoad.length() + 1;
response.persistentBufferFlag = 0;
response.numSendVendorSpecificHeaderOptions = serverHeaderOptions.size();
#include "OCApi.h"
#include "OCException.h"
#include "OCUtilities.h"
+#include "ocpayload.h"
#include "oc_logger.hpp"
return result_guard(OC_STACK_ERROR);
}
- std::string payload(pResponse->getResourceRepresentation().getJSONRepresentation());
-
- return result_guard(
+ OCRepPayload* pl = pResponse->getResourceRepresentation().getPayload();
+ OCStackResult result =
OCNotifyListOfObservers(resourceHandle,
&observationIds[0], observationIds.size(),
- payload.c_str(),
- static_cast<OCQualityOfService>(QoS)));
+ pl,
+ static_cast<OCQualityOfService>(QoS));
+ OCRepPayloadDestroy(pl);
+ return result_guard(result);
}
OCResource::Ptr OCPlatform_impl::constructResourceObject(const std::string& host,
#include <OCRepresentation.h>
#include <boost/lexical_cast.hpp>
-#include <cereal/cereal.hpp>
-#include <cereal/types/map.hpp>
-#include <cereal/types/vector.hpp>
-#include <cereal/types/utility.hpp>
-#include <OicJsonSerializer.hpp>
#include <algorithm>
+#include "ocpayload.h"
+#include "ocrandom.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
-// code needed to serialize a string=>Attribute value map
namespace OC
{
- namespace detail
+
+ void MessageContainer::setPayload(const OCPayload* rep)
{
- template<class Archive>
- class WriteAttributeValue : public boost::static_visitor<>
+ switch(rep->type)
{
- public:
- WriteAttributeValue(const std::string& name, Archive& ar)
- :m_name(name), m_archive(ar)
- {}
-
- template<class T>
- void operator()(const T& value) const
- {
- m_archive(cereal::make_nvp(m_name, value));
- }
- private:
- std::string m_name;
- Archive& m_archive;
- };
+ case PAYLOAD_TYPE_REPRESENTATION:
+ setPayload(reinterpret_cast<const OCRepPayload*>(rep));
+ break;
+ case PAYLOAD_TYPE_DEVICE:
+ setPayload(reinterpret_cast<const OCDevicePayload*>(rep));
+ break;
+ case PAYLOAD_TYPE_PLATFORM:
+ setPayload(reinterpret_cast<const OCPlatformPayload*>(rep));
+ break;
+ default:
+ throw OC::OCException("Invalid Payload type in setPayload");
+ break;
+ }
}
-}
-
-namespace cereal
-{
- // take no action when serializing the null type, because the 'save' below
- // doesn't use the visitor for this type.
- template <class Archive>
- void serialize(Archive&, OC::NullType t)
- {}
- template<class Archive>
- void save(Archive& ar, const std::map<std::string, OC::AttributeValue>& vals)
+ void MessageContainer::setPayload(const OCDevicePayload* payload)
{
- for(const auto& kv : vals)
+ OCRepresentation rep;
+ rep.setUri(payload->uri);
+ char uuidString[UUID_STRING_SIZE];
+ if(payload->sid && RAND_UUID_OK == OCConvertUuidToString(payload->sid, uuidString))
{
- const auto& k = kv.first;
- const auto& v = kv.second;
+ rep[OC_RSRVD_DEVICE_ID] = std::string(uuidString);
+ }
+ else
+ {
+ rep[OC_RSRVD_DEVICE_ID] = std::string();
+ }
+ rep[OC_RSRVD_DEVICE_NAME] = payload->deviceName ?
+ std::string(payload->deviceName) :
+ std::string();
+ rep[OC_RSRVD_SPEC_VERSION] = payload->specVersion ?
+ std::string(payload->specVersion) :
+ std::string();
+ rep[OC_RSRVD_DATA_MODEL_VERSION] = payload->dataModelVersion ?
+ std::string(payload->dataModelVersion) :
+ std::string();
+ m_reps.push_back(std::move(rep));
+ }
+
+ void MessageContainer::setPayload(const OCPlatformPayload* payload)
+ {
+ OCRepresentation rep;
+ rep.setUri(payload->uri);
+
+ rep[OC_RSRVD_PLATFORM_ID] = payload->info.platformID ?
+ std::string(payload->info.platformID) :
+ std::string();
+ rep[OC_RSRVD_MFG_NAME] = payload->info.manufacturerName ?
+ std::string(payload->info.manufacturerName) :
+ std::string();
+ rep[OC_RSRVD_MFG_URL] = payload->info.manufacturerUrl ?
+ std::string(payload->info.manufacturerUrl) :
+ std::string();
+ rep[OC_RSRVD_MODEL_NUM] = payload->info.modelNumber ?
+ std::string(payload->info.modelNumber) :
+ std::string();
+ rep[OC_RSRVD_MFG_DATE] = payload->info.dateOfManufacture ?
+ std::string(payload->info.dateOfManufacture) :
+ std::string();
+ rep[OC_RSRVD_PLATFORM_VERSION] = payload->info.platformVersion ?
+ std::string(payload->info.platformVersion) :
+ std::string();
+ rep[OC_RSRVD_OS_VERSION] = payload->info.operatingSystemVersion ?
+ std::string(payload->info.operatingSystemVersion) :
+ std::string();
+ rep[OC_RSRVD_HARDWARE_VERSION] = payload->info.hardwareVersion ?
+ std::string(payload->info.hardwareVersion) :
+ std::string();
+ rep[OC_RSRVD_FIRMWARE_VERSION] = payload->info.firmwareVersion ?
+ std::string(payload->info.firmwareVersion) :
+ std::string();
+ rep[OC_RSRVD_SUPPORT_URL] = payload->info.supportUrl ?
+ std::string(payload->info.supportUrl) :
+ std::string();
+ rep[OC_RSRVD_SYSTEM_TIME] = payload->info.systemTime ?
+ std::string(payload->info.systemTime) :
+ std::string();
+
+ m_reps.push_back(std::move(rep));
+ }
+
+ void MessageContainer::setPayload(const OCRepPayload* payload)
+ {
+ const OCRepPayload* pl = payload;
+ while(pl)
+ {
+ OCRepresentation cur;
+ cur.setPayload(pl);
+
+ pl = pl->next;
+ this->addRepresentation(cur);
+ }
+ }
- if(v.which() != OC::AttributeValueNullIndex)
+ OCRepPayload* MessageContainer::getPayload() const
+ {
+ OCRepPayload* root = nullptr;
+ for(const auto& r : representations())
+ {
+ if(!root)
{
- OC::detail::WriteAttributeValue<Archive> writer(k,ar);
- boost::apply_visitor(writer, v);
+ root = r.getPayload();
}
else
{
- ar.setNextName(k.c_str());
- ar.writeName();
- ar.saveValue();
+ OCRepPayloadAppend(root, r.getPayload());
}
}
+
+ return root;
}
- template<class Archive>
- void load(Archive& ar, std::map<std::string, OC::AttributeValue>& vals)
+ const std::vector<OCRepresentation>& MessageContainer::representations() const
{
- ar.loadAttributeValues(vals);
+ return m_reps;
+ }
+
+ void MessageContainer::addRepresentation(const OCRepresentation& rep)
+ {
+ m_reps.push_back(rep);
}
}
namespace OC
{
- typedef cereal::JSONOutputArchive OutputArchiveType;
- typedef cereal::JSONInputArchive InputArchiveType;
+ struct get_payload_array: boost::static_visitor<>
+ {
+ template<typename T>
+ void operator()(T& arr)
+ {
+ throw std::logic_error("Invalid calc_dimensions_visitor type");
+ }
+
+ template<typename T>
+ void operator()(std::vector<T>& arr)
+ {
+ root_size_calc<T>();
+ dimensions[0] = arr.size();
+ dimTotal = calcDimTotal(dimensions);
+
+ array = (void*)OICMalloc(dimTotal * root_size);
+
+ for(size_t i = 0; i < dimensions[0]; ++i)
+ {
+ copy_to_array(arr[i], array, i);
+ }
+
+ }
+ template<typename T>
+ void operator()(std::vector<std::vector<T>>& arr)
+ {
+ root_size_calc<T>();
+ dimensions[0] = arr.size();
+ for(size_t i = 0; i < arr.size(); ++i)
+ {
+ dimensions[1] = std::max(dimensions[1], arr[i].size());
+ }
+ dimTotal = calcDimTotal(dimensions);
+ array = (void*)OICCalloc(1, dimTotal * root_size);
+
+ for(size_t i = 0; i < dimensions[0]; ++i)
+ {
+ for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
+ {
+ copy_to_array(arr[i][j], array, i*dimensions[1] + j);
+ }
+ }
+ }
+ template<typename T>
+ void operator()(std::vector<std::vector<std::vector<T>>>& arr)
+ {
+ root_size_calc<T>();
+ dimensions[0] = arr.size();
+ for(size_t i = 0; i < arr.size(); ++i)
+ {
+ dimensions[1] = std::max(dimensions[1], arr[i].size());
+
+ for(size_t j = 0; j < arr[i].size(); ++j)
+ {
+ dimensions[2] = std::max(dimensions[2], arr[i][j].size());
+ }
+ }
+
+ dimTotal = calcDimTotal(dimensions);
+ array = (void*)OICCalloc(1, dimTotal * root_size);
+
+ for(size_t i = 0; i < dimensions[0]; ++i)
+ {
+ for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
+ {
+ for(size_t k = 0; k < dimensions[2] && k < arr[i][j].size(); ++k)
+ {
+ copy_to_array(arr[i][j][k], array,
+ dimensions[2] * j +
+ dimensions[2] * dimensions[1] * i +
+ k);
+ }
+ }
+ }
+ }
+
+ template<typename T>
+ void root_size_calc()
+ {
+ root_size = sizeof(T);
+ }
+
+ template<typename T>
+ void copy_to_array(T item, void* array, size_t pos)
+ {
+ ((T*)array)[pos] = item;
+ }
+
+ size_t dimensions[MAX_REP_ARRAY_DEPTH];
+ size_t root_size;
+ size_t dimTotal;
+ void* array;
+ };
+
+ template<>
+ void get_payload_array::root_size_calc<int>()
+ {
+ root_size = sizeof(int64_t);
+ }
+
+ template<>
+ void get_payload_array::root_size_calc<std::string>()
+ {
+ root_size = sizeof(char*);
+ }
+
+ template<>
+ void get_payload_array::root_size_calc<OC::OCRepresentation>()
+ {
+ root_size = sizeof(OCRepPayload*);
+ }
+
+ template<>
+ void get_payload_array::copy_to_array(int item, void* array, size_t pos)
+ {
+ ((int64_t*)array)[pos] = item;
+ }
+
+ template<>
+ void get_payload_array::copy_to_array(std::_Bit_reference br, void* array, size_t pos)
+ {
+ ((bool*)array)[pos] = static_cast<bool>(br);
+ }
- void MessageContainer::setJSONRepresentation(const std::string& payload)
+ template<>
+ void get_payload_array::copy_to_array(const std::string& item, void* array, size_t pos)
+ {
+ ((char**)array)[pos] = OICStrdup(item.c_str());
+ }
+
+ template<>
+ void get_payload_array::copy_to_array(OC::OCRepresentation item, void* array, size_t pos)
+ {
+ ((OCRepPayload**)array)[pos] = item.getPayload();
+ }
+
+ void OCRepresentation::getPayloadArray(OCRepPayload* payload,
+ const OCRepresentation::AttributeItem& item) const
{
- std::stringstream os(payload);
+ get_payload_array vis{};
+ boost::apply_visitor(vis, m_values[item.attrname()]);
+
+
+ switch(item.base_type())
{
- InputArchiveType archive(os);
- archive(cereal::make_nvp(OC::Key::OCKEY, m_reps));
+ case AttributeType::Integer:
+ OCRepPayloadSetIntArrayAsOwner(payload, item.attrname().c_str(),
+ (int64_t*)vis.array,
+ vis.dimensions);
+ break;
+ case AttributeType::Double:
+ OCRepPayloadSetDoubleArrayAsOwner(payload, item.attrname().c_str(),
+ (double*)vis.array,
+ vis.dimensions);
+ break;
+ case AttributeType::Boolean:
+ OCRepPayloadSetBoolArrayAsOwner(payload, item.attrname().c_str(),
+ (bool*)vis.array,
+ vis.dimensions);
+ break;
+ case AttributeType::String:
+ OCRepPayloadSetStringArrayAsOwner(payload, item.attrname().c_str(),
+ (char**)vis.array,
+ vis.dimensions);
+ break;
+ case AttributeType::OCRepresentation:
+ OCRepPayloadSetPropObjectArrayAsOwner(payload, item.attrname().c_str(),
+ (OCRepPayload**)vis.array, vis.dimensions);
+ break;
+ default:
+ throw std::logic_error(std::string("GetPayloadArray: Not Implemented") +
+ std::to_string((int)item.base_type()));
}
}
- void MessageContainer::setJSONRepresentation(const char* payload)
+ OCRepPayload* OCRepresentation::getPayload() const
{
- setJSONRepresentation(std::string(payload));
+ OCRepPayload* root = OCRepPayloadCreate();
+ if(!root)
+ {
+ throw std::bad_alloc();
+ }
+
+ OCRepPayloadSetUri(root, getUri().c_str());
+
+ for(const std::string& type : getResourceTypes())
+ {
+ OCRepPayloadAddResourceType(root, type.c_str());
+ }
+
+ for(const std::string& iface : getResourceInterfaces())
+ {
+ OCRepPayloadAddInterface(root, iface.c_str());
+ }
+
+ for(auto& val : *this)
+ {
+ switch(val.type())
+ {
+ case AttributeType::Null:
+ OCRepPayloadSetNull(root, val.attrname().c_str());
+ break;
+ case AttributeType::Integer:
+ OCRepPayloadSetPropInt(root, val.attrname().c_str(), static_cast<int>(val));
+ break;
+ case AttributeType::Double:
+ OCRepPayloadSetPropDouble(root, val.attrname().c_str(), val);
+ break;
+ case AttributeType::Boolean:
+ OCRepPayloadSetPropBool(root, val.attrname().c_str(), val);
+ break;
+ case AttributeType::String:
+ OCRepPayloadSetPropString(root, val.attrname().c_str(),
+ static_cast<std::string>(val).c_str());
+ break;
+ case AttributeType::OCRepresentation:
+ OCRepPayloadSetPropObjectAsOwner(root, val.attrname().c_str(),
+ static_cast<OCRepresentation>(val).getPayload());
+ break;
+ case AttributeType::Vector:
+ getPayloadArray(root, val);
+ break;
+ default:
+ throw std::logic_error(std::string("Getpayload: Not Implemented") +
+ std::to_string((int)val.type()));
+ break;
+ }
+ }
+
+ OCRepPayload* cur = root;
+ for(auto& child : this->getChildren())
+ {
+ cur->next = child.getPayload();
+ cur = cur->next;
+ }
+
+ return root;
}
- std::string MessageContainer::getJSONRepresentation(OCInfoFormat f) const
+ size_t calcArrayDepth(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
{
- std::stringstream os;
+ if(dimensions[0] == 0)
+ {
+ throw std::logic_error("invalid calcArrayDepth");
+ }
+ else if(dimensions[1] == 0)
+ {
+ return 1;
+ }
+ else if (dimensions[2] == 0)
+ {
+ return 2;
+ }
+ else
+ {
+ return 3;
+ }
+ }
+
+ template<typename T>
+ T OCRepresentation::payload_array_helper_copy(size_t index, const OCRepPayloadValue* pl)
+ {
+ throw std::logic_error("payload_array_helper_copy: unsupported type");
+ }
+ template<>
+ int OCRepresentation::payload_array_helper_copy<int>(size_t index, const OCRepPayloadValue* pl)
+ {
+ return pl->arr.iArray[index];
+ }
+ template<>
+ double OCRepresentation::payload_array_helper_copy<double>(size_t index, const OCRepPayloadValue* pl)
+ {
+ return pl->arr.dArray[index];
+ }
+ template<>
+ bool OCRepresentation::payload_array_helper_copy<bool>(size_t index, const OCRepPayloadValue* pl)
+ {
+ return pl->arr.bArray[index];
+ }
+ template<>
+ std::string OCRepresentation::payload_array_helper_copy<std::string>(
+ size_t index, const OCRepPayloadValue* pl)
+ {
+ return std::string(pl->arr.strArray[index]);
+ }
+ template<>
+ OCRepresentation OCRepresentation::payload_array_helper_copy<OCRepresentation>(
+ size_t index, const OCRepPayloadValue* pl)
+ {
+ OCRepresentation r;
+ r.setPayload(pl->arr.objArray[index]);
+ return r;
+ }
- // note: the block is required because cereal closes the JSON string
- // upon destruction, so the archive needs to be destroyed before accessing
- // the data
+ template<typename T>
+ void OCRepresentation::payload_array_helper(const OCRepPayloadValue* pl, size_t depth)
+ {
+ if(depth == 1)
{
- if(f == OCInfoFormat::IncludeOC)
+ std::vector<T> val(pl->arr.dimensions[0]);
+
+ for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
{
- OutputArchiveType archive(os);
- archive(cereal::make_nvp(OC::Key::OCKEY, m_reps));
+ val[i] = payload_array_helper_copy<T>(i, pl);
}
- else if(f== OCInfoFormat::ExcludeOC)
+ this->setValue(std::string(pl->name), val);
+ }
+ else if (depth == 2)
+ {
+ std::vector<std::vector<T>> val(pl->arr.dimensions[0]);
+ for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
{
- bool firstPrinted = false;
- for(std::vector<OCRepresentation>::size_type i = 0; i< m_reps.size();++i)
+ val[i].reserve(pl->arr.dimensions[1]);
+ for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
{
- if(!m_reps[i].emptyData())
+ val[i][j] = payload_array_helper_copy<T>(
+ i * pl->arr.dimensions[1] + j, pl);
+ }
+ }
+ this->setValue(std::string(pl->name), val);
+ }
+ else if (depth == 3)
+ {
+ std::vector<std::vector<std::vector<T>>> val;
+ for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
+ {
+ val[i].reserve(pl->arr.dimensions[1]);
+ for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
+ {
+ val[i][j].reserve(pl->arr.dimensions[2]);
+ for(size_t k = 0; k < pl->arr.dimensions[2]; ++k)
{
- if(firstPrinted)
- {
- os<<',';
- }
- firstPrinted=true;
- os << m_reps[i].getJSONRepresentation();
+ val[i][j][k] = payload_array_helper_copy<T>(
+ pl->arr.dimensions[2] * j +
+ pl->arr.dimensions[2] * pl->arr.dimensions[1] * i +
+ k,
+ pl);
}
}
}
+ this->setValue(std::string(pl->name), val);
+ }
+ else
+ {
+ throw std::logic_error("Invalid depth in payload_array_helper");
}
- return os.str();
}
- const std::vector<OCRepresentation>& MessageContainer::representations() const
+ void OCRepresentation::setPayloadArray(const OCRepPayloadValue* pl)
{
- return m_reps;
- }
- void MessageContainer::addRepresentation(const OCRepresentation& rep)
- {
- m_reps.push_back(rep);
+ switch(pl->arr.type)
+ {
+ case OCREP_PROP_INT:
+ payload_array_helper<int>(pl, calcArrayDepth(pl->arr.dimensions));
+ break;
+ case OCREP_PROP_DOUBLE:
+ payload_array_helper<double>(pl, calcArrayDepth(pl->arr.dimensions));
+ break;
+ case OCREP_PROP_BOOL:
+ payload_array_helper<bool>(pl, calcArrayDepth(pl->arr.dimensions));
+ break;
+ case OCREP_PROP_STRING:
+ payload_array_helper<std::string>(pl, calcArrayDepth(pl->arr.dimensions));
+ break;
+ case OCREP_PROP_OBJECT:
+ payload_array_helper<OCRepresentation>(pl, calcArrayDepth(pl->arr.dimensions));
+ break;
+ default:
+ throw std::logic_error("setPayload array invalid type");
+ break;
+ }
}
-}
-namespace OC
-{
- std::string OCRepresentation::getJSONRepresentation() const
+ void OCRepresentation::setPayload(const OCRepPayload* pl)
{
- if(emptyData())
+ setUri(pl->uri);
+
+ OCStringLL* ll = pl->types;
+ while(ll)
{
- return "{}";
+ addResourceType(ll->value);
+ ll = ll->next;
}
- std::stringstream os;
-
- // note: the block is required because cereal closes the JSON string
- // upon destruction, so the archive needs to be destroyed before accessing
- // the data
+ ll = pl->interfaces;
+ while(ll)
{
- OutputArchiveType archive (os);
- save(archive);
+ addResourceInterface(ll->value);
+ ll = ll->next;
}
- return os.str();
+ OCRepPayloadValue* val = pl->values;
+
+ while(val)
+ {
+ switch(val->type)
+ {
+ case OCREP_PROP_NULL:
+ setNULL(val->name);
+ break;
+ case OCREP_PROP_INT:
+ setValue<int>(val->name, val->i);
+ break;
+ case OCREP_PROP_DOUBLE:
+ setValue<double>(val->name, val->d);
+ break;
+ case OCREP_PROP_BOOL:
+ setValue<bool>(val->name, val->b);
+ break;
+ case OCREP_PROP_STRING:
+ setValue<std::string>(val->name, val->str);
+ break;
+ case OCREP_PROP_OBJECT:
+ {
+ OCRepresentation cur;
+ cur.setPayload(val->obj);
+ setValue<OCRepresentation>(val->name, cur);
+ }
+ break;
+ case OCREP_PROP_ARRAY:
+ setPayloadArray(val);
+ break;
+ default:
+ throw std::logic_error(std::string("Not Implemented!") +
+ std::to_string((int)val->type));
+ break;
+ }
+ val = val->next;
+ }
}
void OCRepresentation::addChild(const OCRepresentation& rep)
m_resourceTypes = resourceTypes;
}
+ void OCRepresentation::addResourceType(const std::string& str)
+ {
+ m_resourceTypes.push_back(str);
+ }
+
const std::vector<std::string>& OCRepresentation::getResourceInterfaces() const
{
return m_interfaces;
}
+ void OCRepresentation::addResourceInterface(const std::string& str)
+ {
+ m_interfaces.push_back(str);
+ }
+
void OCRepresentation::setResourceInterfaces(const std::vector<std::string>& resourceInterfaces)
{
m_interfaces = resourceInterfaces;
namespace OC
{
- template <class Archive, class Val>
- void OCRepresentation::optional_load(Archive& ar, Val&& v)
- {
- try
- {
- ar(v);
- }
- catch(cereal::Exception&)
- {
- ar.setNextName(nullptr);
- // Loading a key that doesn't exist results in an exception
- // Since "Not Found" is a valid condition for us, we swallow
- // this exception and the archive will not load anything
- }
- }
-
- template<class Archive>
- void OCRepresentation::save(Archive& ar) const
- {
- // printed for all interface types
- if(!m_uri.empty())
- {
- ar(cereal::make_nvp(Key::URIKEY, m_uri));
- }
-
- if((m_interfaceType == InterfaceType::None
- || m_interfaceType==InterfaceType::DefaultChild
- || m_interfaceType==InterfaceType::LinkChild)
- && (m_resourceTypes.size()>0 || m_interfaces.size()>0))
- {
- // The Prop object requires that it refer to non-const vectors
- // so that it can alter them in the 'load' case. In the save case
- // (initiated here) it will not modify the object. So, to keep the
- // compiler happy, removing the 'const' context here is necessary.
- const std::vector<std::string>& rt(m_resourceTypes);
- const std::vector<std::string>& intf(m_interfaces);
- Prop temp(const_cast<std::vector<std::string>&>(rt),
- const_cast<std::vector<std::string>&>(intf));
- ar(cereal::make_nvp(Key::PROPERTYKEY, temp));
- }
-
- // printed only for BatchChildren and DefaultParent
- if((m_interfaceType == InterfaceType::None
- || m_interfaceType == InterfaceType::BatchChild
- || m_interfaceType == InterfaceType::DefaultParent)
- && m_values.size()>0)
- {
- ar(cereal::make_nvp(Key::REPKEY, m_values));
- }
- }
-
- template<class Archive>
- void OCRepresentation::load(Archive& ar)
- {
- optional_load(ar, cereal::make_nvp(Key::URIKEY, m_uri));
- {
- Prop temp(m_resourceTypes, m_interfaces);
- optional_load(ar, cereal::make_nvp(Key::PROPERTYKEY, temp));
- }
- optional_load(ar, cereal::make_nvp(Key::REPKEY, m_values));
- }
-
- template<class Archive>
- void OCRepresentation::Prop::save(Archive& ar) const
- {
- if(m_types.size() > 0)
- {
- ar(cereal::make_nvp(Key::RESOURCETYPESKEY, m_types));
- }
-
- if(m_interfaces.size()>0)
- {
- ar(cereal::make_nvp(Key::INTERFACESKEY, m_interfaces));
- }
- }
-
- template<class Archive>
- void OCRepresentation::Prop::load(Archive& ar)
- {
- optional_load(ar, cereal::make_nvp(Key::RESOURCETYPESKEY, m_types));
- optional_load(ar, cereal::make_nvp(Key::INTERFACESKEY, m_interfaces));
- }
-}
-
-// note: the below is used to load an AttributeValue map out of JSON
-namespace OC
-{
- namespace detail
- {
- enum class typeTag:uint8_t
- {
- NOTHING = 0,
- _string,
- _int,
- _double,
- _bool,
- _representation
- };
-
- typedef rapidjson::Document::GenericValue GenericValue;
-
- AttributeValue parseAttributeValue(const GenericValue& v);
- AttributeValue parseAttributeValue(const GenericValue& v,
- const unsigned int curLevel, unsigned int& maxDepth, typeTag& t);
- AttributeValue parseAttributeValueObject(const GenericValue& v, typeTag& t);
- AttributeValue parseAttributeValueArray(const GenericValue& v,
- const unsigned int curLevel, unsigned int& maxDepth, typeTag& t);
- AttributeValue parseAttributeValuePrimitive(const GenericValue& v, typeTag& t);
-
- AttributeValue parseAttributeValue(const GenericValue& v)
- {
- // base entrance, start everything at '0'
- unsigned int max_depth {0};
- typeTag t {typeTag::NOTHING};
-
- return parseAttributeValue(v, 0, max_depth, t);
- }
-
- AttributeValue parseAttributeValue(const GenericValue& v,
- const unsigned int curLevel, unsigned int& maxDepth, typeTag& t)
- {
- if(v.IsObject())
- {
- return parseAttributeValueObject(v, t);
- }
- else if(v.IsArray())
- {
- return parseAttributeValueArray(v, curLevel + 1, maxDepth, t);
- }
- else
- {
- return parseAttributeValuePrimitive(v,t);
- }
- }
-
- AttributeValue parseAttributeValueObject(const GenericValue& v, typeTag& t)
- {
- typedef rapidjson::Value::ConstMemberIterator CMI;
- t = typeTag::_representation;
- OC::OCRepresentation rep;
-
- for(CMI itr = v.MemberBegin(); itr!= v.MemberEnd(); ++itr)
- {
- std::string keyName = itr->name.GetString();
-
- if(keyName == OC::Key::URIKEY)
- {
- rep.setUri(boost::get<std::string>(parseAttributeValue(itr->value)));
- }
- else if (keyName == OC::Key::PROPERTYKEY)
- {
- for(CMI itr2 = itr->value.MemberBegin();
- itr->value.MemberEnd()!=itr2;
- ++itr2)
- {
- if(keyName == OC::Key::RESOURCETYPESKEY)
- {
- rep.setResourceTypes(
- boost::get<std::vector<std::string>>(
- parseAttributeValue(itr->value)));
- }
- else if(keyName == OC::Key::INTERFACESKEY)
- {
- rep.setResourceInterfaces(
- boost::get<std::vector<std::string>>(
- parseAttributeValue(itr->value)));
- }
- }
- }
- else if (keyName == OC::Key::REPKEY)
- {
- for(CMI itr2 = itr->value.MemberBegin();
- itr->value.MemberEnd()!=itr2;
- ++itr2)
- {
- rep.setValue(itr2->name.GetString(),
- parseAttributeValue(itr2->value));
- }
- }
- }
-
- return rep;
- }
-
- AttributeValue parseAttributeValuePrimitive(const GenericValue& v, typeTag& t)
- {
- if(v.IsString())
- {
- t = typeTag::_string;
- return std::string(v.GetString());
- }
- else if (v.IsNumber())
- {
- if(v.IsDouble())
- {
- t = typeTag::_double;
- return double(v.GetDouble());
- }
- else if (v.IsInt())
- {
- t = typeTag::_int;
- return int(v.GetInt());
- }
- else
- {
- throw OC::OCException(OC::Exception::INVALID_JSON_NUMERIC
- + std::to_string(v.GetType()));
- }
- }
- else if(v.IsBool_())
- {
- t=typeTag::_bool;
- return bool(v.GetBool_());
- }
- else if(v.IsNull_())
- {
- return OC::NullType();
- }
- else
- {
- throw OC::OCException(OC::Exception::INVALID_JSON_TYPE
- + std::to_string(v.GetType()));
- }
- }
-
- std::vector<AttributeValue> gatherArrayContents(const GenericValue& v,
- const unsigned int curLevel, unsigned int& maxDepth, typeTag& t)
- {
- std::vector<AttributeValue> out;
-
- std::transform(v.Begin(), v.End(), back_inserter(out),
- [curLevel, &maxDepth, &t](const GenericValue& x)
- {
- return parseAttributeValue(x, curLevel, maxDepth, t);
- });
- return out;
- }
-
- template<class OutT>
- struct valueToConcrete
- {
- OutT operator()(const AttributeValue& v)
- {
- return boost::get<OutT>(v);
- }
-
- };
-
- template <class OutSeqT>
- OutSeqT valuesToConcreteVectors(const std::vector<AttributeValue>& vs)
- {
- OutSeqT ret;
-
- std::transform(begin(vs),end(vs), back_inserter(ret),
- valueToConcrete<typename OutSeqT::value_type>());
- return ret;
- }
-
- template<class valueType>
- AttributeValue remapArrayDepth(const unsigned int curLevel,
- const std::vector<OC::AttributeValue>& vs)
- {
- switch(curLevel)
- {
- default:
- throw OC::OCException(OC::Exception::INVALID_JSON_ARRAY_DEPTH);
- break;
- case 1:
- return valuesToConcreteVectors<std::vector<valueType>>(vs);
- break;
- case 2:
- return valuesToConcreteVectors<std::vector<std::vector<valueType>>>(vs);
- break;
- case 3:
- return valuesToConcreteVectors
- <std::vector<std::vector<std::vector<valueType>>>>(vs);
- break;
- }
- }
-
- AttributeValue convertArrayToConcretes(const typeTag t,
- const unsigned int curLevel, const std::vector<OC::AttributeValue>& vs)
- {
- // This function converts a std::vector of AttributeValue to a std::vector
- // of concrete types. Since we don't use a recursive Variant, we need
- // to get back to a 'base' primitive type
- switch(t)
- {
- default:
- case typeTag::NOTHING:
- throw OC::OCException(OC::Exception::INVALID_JSON_TYPE_TAG);
- break;
- case typeTag::_string:
- return remapArrayDepth<std::string>(curLevel, vs);
- break;
- case typeTag::_int:
- return remapArrayDepth<int>(curLevel, vs);
- break;
- case typeTag::_double:
- return remapArrayDepth<double>(curLevel, vs);
- break;
- case typeTag::_bool:
- return remapArrayDepth<bool>(curLevel, vs);
- break;
- case typeTag::_representation:
- return remapArrayDepth<OCRepresentation>(curLevel, vs);
- break;
- }
- }
-
- AttributeValue parseAttributeValueArray(const GenericValue& v,
- const unsigned int curLevel, unsigned int& maxDepth, typeTag& t)
- {
- const unsigned int max_level = 3;
-
- if(curLevel > max_level)
- {
- throw OC::OCException(OC::Exception::INVALID_JSON_ARRAY_DEPTH);
- }
-
- if(curLevel > maxDepth)
- {
- maxDepth = curLevel;
- }
-
- auto arrayItems = gatherArrayContents(v, curLevel, maxDepth, t);
- const int remapLevel = maxDepth - (curLevel -1);
- return convertArrayToConcretes(t, remapLevel, arrayItems);
- }
- }
-}
-
-namespace cereal
-{
- void JSONInputArchive::loadAttributeValues(std::map<std::string, OC::AttributeValue>& map)
- {
- for(auto&b = itsIteratorStack.back();
- b.Member && b.itsMemberItEnd != b.itsMemberItBegin+b.itsIndex;
- ++b)
- {
- std::string key = b.itsMemberItBegin[b.itsIndex].name.GetString();
- const GenericValue& v = itsIteratorStack.back().value();
- map[key] = OC::detail::parseAttributeValue(v);
- }
- }
-}
-
-namespace OC
-{
std::ostream& operator <<(std::ostream& os, const AttributeType at)
{
switch(at)
#include <vector>
#include <map>
-#include <cereal/cereal.hpp>
-#include <OicJsonSerializer.hpp>
+#include "ocpayload.h"
using namespace OC;
-using namespace std;
-void OCResourceRequest::setPayload(const std::string& requestPayload)
+void OCResourceRequest::setPayload(OCPayload* payload)
{
MessageContainer info;
- if(requestPayload.empty())
+ if(payload == nullptr || payload->type != PAYLOAD_TYPE_REPRESENTATION)
{
+ throw std::logic_error("Wrong payload type");
return;
}
- try
- {
- info.setJSONRepresentation(requestPayload);
- }
- catch(cereal::RapidJSONException& ex)
- {
- oclog() << "RapidJSON Exception in setPayload: "<<ex.what()<<std::endl<<
- "Data was:"<<requestPayload<<std::flush;
- return;
- }
- catch(cereal::Exception& ex)
- {
- oclog() << "Cereal Exception in setPayload: "<<ex.what()<<std::endl<<
- "Data was:"<<requestPayload<<std::flush;
- return;
- }
+ info.setPayload(payload);
const std::vector<OCRepresentation>& reps = info.representations();
if(reps.size() >0)
'OCResourceRequest.cpp'
]
-oclib_env.AppendUnique(CPPPATH = [oclib_env.get('SRC_DIR') + '/extlibs/cereal/include'])
oclib = oclib_env.SharedLibrary('oc', oclib_src)
oclib_env.InstallTarget(oclib, 'liboc')
oclib_env.UserInstallTargetLib(oclib, 'liboc')
{
OC_LOG_V(DEBUG, HOSTING_TAG, "\tStackResult: %s", getResultString(clientResponse->result));
OC_LOG_V(DEBUG, HOSTING_TAG, "\tStackResult: %d", clientResponse->result);
- OC_LOG_V(DEBUG, HOSTING_TAG,
- "\tPresence Device =============> Presence %s @ %s:%d",
- clientResponse->resJSONPayload,
- clientResponse->devAddr.addr,
- clientResponse->devAddr.port);
+ //OC_LOG_V(DEBUG, HOSTING_TAG,
+ // "\tPresence Device =============> Presence %s @ %s:%d",
+ // clientResponse->resJSONPayload,
+ // clientResponse->devAddr.addr,
+ // clientResponse->devAddr.port);
snprintf(address, sizeof(address), "%s:%d",
clientResponse->devAddr.addr,
{
cJSON *discoveryJson = cJSON_CreateObject();
- discoveryJson = cJSON_Parse((char *)clientResponse->resJSONPayload);
+ //discoveryJson = cJSON_Parse((char *)clientResponse->resJSONPayload);
cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, "oc");
char *ocArray_str = cJSON_PrintUnformatted(ocArray);
clientResponse->devAddr.addr,
clientResponse->devAddr.port);
- OC_LOG_V(DEBUG, HOSTING_TAG, "Host Device =============> Discovered %s @ %s",
- clientResponse->resJSONPayload, sourceaddr);
+ //OC_LOG_V(DEBUG, HOSTING_TAG, "Host Device =============> Discovered %s @ %s",
+ // clientResponse->resJSONPayload, sourceaddr);
int arraySize = cJSON_GetArraySize(ocArray);
for (int i = 0; i < arraySize; ++i)
OC_LOG_V(DEBUG, HOSTING_TAG,
"<=============Callback Context for OBSERVE notification recvd successfully");
OC_LOG_V(DEBUG, HOSTING_TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
- OC_LOG_V(DEBUG, HOSTING_TAG, "JSON = %s =============> Obs Response",
- clientResponse->resJSONPayload);
+ //OC_LOG_V(DEBUG, HOSTING_TAG, "JSON = %s =============> Obs Response",
+ // clientResponse->resJSONPayload);
- MirrorResource *foundMirrorResource = updateMirrorResource(handle, clientResponse->resJSONPayload);
+ MirrorResource *foundMirrorResource = NULL;//updateMirrorResource(handle, clientResponse->resJSONPayload);
if (foundMirrorResource == NULL)
{
OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found Mirror Resource : Fail");
mirrorResource->rep = NULL;
}
mirrorResource->rep = cJSON_CreateObject();
- mirrorResource->rep = cJSON_Parse(entityHandlerRequest->reqJSONPayload);
+ //mirrorResource->rep = cJSON_Parse(entityHandlerRequest->reqJSONPayload);
}
OC_LOG_V(DEBUG, HOSTING_TAG, "node's uri : %s", mirrorResource->uri);
entityHandlerResponse.requestHandle = entityHandlerRequest->requestHandle;
entityHandlerResponse.resourceHandle = entityHandlerRequest->resource;
entityHandlerResponse.ehResult = entityHandlerResult;
- entityHandlerResponse.payload = (char *)payload;
- entityHandlerResponse.payloadSize = strlen(payload);
+ //entityHandlerResponse.payload = (char *)payload;
+ //entityHandlerResponse.payloadSize = strlen(payload);
// Indicate that response is NOT in a persistent buffer
entityHandlerResponse.persistentBufferFlag = 0;
if(method == OC_REST_PUT)
{
char payload[OIC_STRING_MAX_VALUE] = {'\0'};
- snprintf(payload , sizeof(payload), "%s" ,
- ((OCEntityHandlerRequest*)request->requestHandle[OIC_REQUEST_BY_CLIENT])->reqJSONPayload);
+ //snprintf(payload , sizeof(payload), "%s" ,
+ // ((OCEntityHandlerRequest*)request->requestHandle[OIC_REQUEST_BY_CLIENT])->reqJSONPayload);
- result = OCDoResource(&request->requestHandle[OIC_REQUEST_BY_COORDINATOR],
- method, queryFullUri, NULL, payload, OC_TRANSPORT, OC_LOW_QOS, &cbData, NULL, 0);
+ //result = OCDoResource(&request->requestHandle[OIC_REQUEST_BY_COORDINATOR],
+ // method, queryFullUri, NULL, payload, OC_TRANSPORT, OC_LOW_QOS, &cbData, NULL, 0);
}
else
{
}
else
{
- OC_LOG_V(DEBUG, HOSTING_TAG, "requestCB's payload: %s", clientResponse->resJSONPayload);
+ //OC_LOG_V(DEBUG, HOSTING_TAG, "requestCB's payload: %s", clientResponse->resJSONPayload);
OCEntityHandlerRequest *entityHandler = (OCEntityHandlerRequest *)(
request->requestHandle[OIC_REQUEST_BY_CLIENT]);
OC_LOG_V(DEBUG, HOSTING_TAG, "requested resource handle : %u", entityHandler->resource
entityHandler->method = request->method;
entityHandler->requestHandle = request->entityRequestHandle;
- OCEntityHandlerResponse response = buildEntityHandlerResponse(
- entityHandler, clientResponse->resJSONPayload);
+ OCEntityHandlerResponse response; //= buildEntityHandlerResponse(
+ //entityHandler, clientResponse->resJSONPayload);
if (OCDoResponse(&response) != OC_STACK_OK)
{
OC_LOG_V(DEBUG, HOSTING_TAG, "Error sending response");
cJSON_Delete(observeJson);
- entityHandlerRequest->reqJSONPayload = temp;
+ //entityHandlerRequest->reqJSONPayload = temp;
}
entityHandlerResult = handleRequestPayload(entityHandlerRequest, payload, sizeof(payload) - 1);
response.resourceHandle = entityHandlerRequest->resource;
response.ehResult = entityHandlerResult;
- response.payload = (char *)payload;
- response.payloadSize = strlen(payload);
+ //response.payload = (char *)payload;
+ //response.payloadSize = strlen(payload);
// Indicate that response is NOT in a persistent buffer
response.persistentBufferFlag = 0;
scp -p -P 29418 ${GIT_USER}@gerrit.iotivity.org:hooks/commit-msg iotivity/.git/hooks/
fi
-export CEREAL_DIR=iotivity/extlibs/cereal
+export TINYCBOR_DIR=iotivity/extlibs/tinycbor
if [ ! -d ${CEREAL_DIR} ]
then
- git clone https://github.com/USCiLab/cereal.git ${CEREAL_DIR}
- pushd ${CEREAL_DIR}
- git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245
- git apply ../../resource/patches/cereal_gcc46.patch
- popd
+ git clone https://github.com/01org/tinycbor ${CEREAL_DIR}
fi
#######################################
-# Android
+# Android
#######################################
echo "Set up Android NDK"