* @return ::OC_STACK_OK on success, some other value upon failure.
*/
OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge,
- OCResourceType *resourceType, OCQualityOfService qos);
+ OCPresenceTrigger trigger, OCResourceType *resourceType, OCQualityOfService qos);
#else
/**
* Create an observe response and send to all observers in the observe list.
const uint8_t numOptions, const CAHeaderOption_t *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.
*
* @param resourceType Handle to the resourceType linked list of resource
* that was modified.
+ * @param trigger The simplified reason this API was invoked. Valid values are
+ * @ref OC_PRESENCE_TRIGGER_CREATE, @ref OC_PRESENCE_TRIGGER_CHANGE,
+ * @ref OC_PRESENCE_TRIGGER_DELETE.
* @return ::OC_STACK_OK on success, some other value upon failure.
*/
-OCStackResult SendPresenceNotification(OCResourceType *resourceType);
+OCStackResult SendPresenceNotification(OCResourceType *resourceType,
+ OCPresenceTrigger trigger);
/**
* Send Stop Notification to Presence subscribers.
OCResourceProperty resourceProperties, uint8_t enable);
#endif
+/**
+ * Clones a string IFF its pointer value is not NULL.
+ *
+ * Note: The caller to this function is responsible for calling @ref OCFree
+ * for the destination parameter.
+ *
+ * @param dest The destination string for the string value to be cloned.
+ *
+ * @param src The source for the string value to be to cloned.
+ */
+OCStackResult CloneStringIfNonNull(char **dest, const char *src);
+
+
+const char *convertTriggerEnumToString(OCPresenceTrigger trigger);
+
+OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr);
+
#ifdef __cplusplus
}
#endif // __cplusplus
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
-#define WITH_PRESENCE
#define USE_RANDOM_PORT (0)
//-----------------------------------------------------------------------------
#define OC_RSRVD_RESOURCE_TYPE "rt"
#define OC_RSRVD_RESOURCE_TYPE_PRESENCE "oic.wk.ad"
#define OC_RSRVD_INTERFACE "if"
-
+#define OC_RSRVD_TTL "ttl"
+#define OC_RSRVD_NONCE "non"
+#define OC_RSRVD_TRIGGER "trg"
#define OC_RSRVD_INTERFACE_DEFAULT "oic.if.baseline"
#define OC_RSRVD_INTERFACE_LL "oic.if.ll"
#define OC_RSRVD_HOSTING_PORT "port"
#define OC_RSRVD_SERVER_INSTANCE_ID "sid"
- //**** Platform ****
+//**** Presence "Announcement Triggers" ****
+#define OC_RSRVD_TRIGGER_CREATE "create"
+#define OC_RSRVD_TRIGGER_CHANGE "change"
+#define OC_RSRVD_TRIGGER_DELETE "delete"
+//*******************
+
+//**** Platform ****
#define OC_RSRVD_PLATFORM_ID "pi"
#define OC_RSRVD_MFG_NAME "mnmn"
#define OC_RSRVD_MFG_URL "mnml"
#define OC_RSRVD_SYSTEM_TIME "st"
//*******************
- //**** Device ****
+//**** Device ****
#define OC_RSRVD_DEVICE_ID "di"
#define OC_RSRVD_DEVICE_NAME "n"
#define OC_RSRVD_SPEC_VERSION "lcv"
#include "ocrandom.h"
#include "ocmalloc.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)
+{
+ cJSON *rootObj = cJSON_CreateObject();
+ if (!rootObj)
+ {
+ return NULL;
+ }
+
+ char *jsonEncodedInfo = NULL;
+ const char * triggerStr = NULL;
+ 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)
+ {
+ strncpy(out, jsonStr, (jsonLen + 1));
+ *remaining = *remaining - jsonLen;
+ ret = OC_STACK_OK;
+ }
+ else
+ {
+ ret = OC_STACK_ERROR;
+ }
+
+ OCFree(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.
#ifdef WITH_PRESENCE
OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge,
- OCResourceType *resourceType, OCQualityOfService qos)
+ OCPresenceTrigger trigger, OCResourceType *resourceType, OCQualityOfService qos)
#else
OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge,
OCQualityOfService qos)
if(result == OC_STACK_OK)
{
- // we create the payload here
- if(resourceType && resourceType->resourcetypename)
- {
- snprintf((char *)presenceResBuf, sizeof(presenceResBuf), "%u:%u:%s",
- resPtr->sequenceNum, maxAge, resourceType->resourcetypename);
- }
- else
+ uint16_t remaining = MAX_RESPONSE_LENGTH;
+ // create the payload here
+ result = BuildPresenceResponse(presenceResBuf, &remaining,
+ maxAge, resPtr->sequenceNum, trigger,
+ resourceType);
+
+ if(result == OC_STACK_OK && remaining < MAX_RESPONSE_LENGTH)
{
- snprintf((char *)presenceResBuf, sizeof(presenceResBuf), "%u:%u",
- resPtr->sequenceNum, maxAge);
+ ehResponse.ehResult = OC_EH_OK;
+ ehResponse.payload = presenceResBuf;
+ ehResponse.payloadSize = strlen((const char *)presenceResBuf) + 1;
+ ehResponse.persistentBufferFlag = 0;
+ ehResponse.requestHandle = (OCRequestHandle) request;
+ ehResponse.resourceHandle = (OCResourceHandle) resPtr;
+ strcpy((char *)ehResponse.resourceUri,
+ (const char *)resourceObserver->resUri);
+ result = OCDoResponse(&ehResponse);
}
- ehResponse.ehResult = OC_EH_OK;
- ehResponse.payload = presenceResBuf;
- ehResponse.payloadSize = strlen((const char *)presenceResBuf) + 1;
- ehResponse.persistentBufferFlag = 0;
- ehResponse.requestHandle = (OCRequestHandle) request;
- ehResponse.resourceHandle = (OCResourceHandle) resPtr;
- strcpy((char *)ehResponse.resourceUri, (const char *)resourceObserver->resUri);
- result = OCDoResponse(&ehResponse);
}
}
#endif
else
{
if(resource->resourceProperties & OC_ACTIVE){
- SendPresenceNotification(NULL);
+ SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
}
}
#endif
savedPlatformInfo.systemTime = NULL;
}
-static OCStackResult CloneStringIfNonNull(char **dest, char *src)
-{
- if (src)
- {
- *dest = (char*) OCMalloc(strlen(src) + 1);
- if (!*dest)
- {
- return OC_STACK_NO_MEMORY;
- }
- strcpy(*dest, src);
- }
- else
- {
- *dest = NULL;
- }
- return OC_STACK_OK;
-}
-
static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
{
OCStackResult ret = OC_STACK_OK;
#include "coap_time.h"
#include "utlist.h"
#include "pdu.h"
+#include "cJSON.h"
#ifndef ARDUINO
#include <arpa/inet.h>
* @param maxAge Time To Live (in seconds).
* @param resType Resource type.
*/
-// TODO: Not sure if I agree with this. I think it should be static but it is called in
-// stack/test/stacktests.cpp, not included via a header file. If we intend to allow it
-// to be called externally, we should change the name to OCParsePresencePayload and make
-// it part of the official public API. But can't change now due to current API freeze.
-// Another option might be to make non-API utility functions for doing stuff like this.
-void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge, char** resType);
+void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge,
+ OCPresenceTrigger *presenceTrigger, char** resType);
//-----------------------------------------------------------------------------
// Private internal function prototypes
return UINT32_MAX;
}
}
+/**
+ * Clones a string IFF its pointer value is not NULL.
+ *
+ * Note: The caller to this function is responsible for calling @ref OCFree
+ * for the destination parameter.
+ *
+ * @param dest The destination string for the string value to be cloned.
+ *
+ * @param src The source for the string value to be to cloned.
+ */
+OCStackResult CloneStringIfNonNull(char **dest, const char *src)
+{
+ if (src)
+ {
+ *dest = (char*) OCMalloc(strlen(src) + 1);
+ if (!*dest)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+ strcpy(*dest, src);
+ }
+ else
+ {
+ *dest = NULL;
+ }
+ return OC_STACK_OK;
+}
OCStackResult OCBuildIPv4Address(uint8_t a, uint8_t b, uint8_t c, uint8_t d,
uint16_t port, OCDevAddr *ipAddr)
return OC_STACK_OK;
}
-void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge, char** resType)
+const char *convertTriggerEnumToString(OCPresenceTrigger trigger)
{
- char * tok = NULL;
- char * savePtr = NULL;
- // The format of the payload is {"oic":[%u:%u:%s]}
- // %u : sequence number,
- // %u : max age
- // %s : Resource Type (Optional)
-
- if (!payload || !seqNum || !maxAge || !resType)
+ if(trigger == OC_PRESENCE_TRIGGER_CREATE)
{
- return;
+ return OC_RSRVD_TRIGGER_CREATE;
}
- tok = strtok_r(payload, "[:]}", &savePtr);
- payload[strlen(payload)] = ':';
-
- //Retrieve sequence number
- tok = strtok_r(NULL, "[:]}", &savePtr);
- if(tok == NULL)
+ else if(trigger == OC_PRESENCE_TRIGGER_CHANGE)
{
- return;
+ return OC_RSRVD_TRIGGER_CHANGE;
}
- payload[strlen((char *)payload)] = ':';
- *seqNum = (uint32_t) atoi(tok);
+ else
+ {
+ return OC_RSRVD_TRIGGER_DELETE;
+ }
+}
- //Retrieve MaxAge
- tok = strtok_r(NULL, "[:]}", &savePtr);
- if(tok == NULL)
+OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr)
+{
+ if(strcmp(triggerStr, OC_RSRVD_TRIGGER_CREATE) == 0)
{
- return;
+ return OC_PRESENCE_TRIGGER_CREATE;
+ }
+ else if(strcmp(triggerStr, OC_RSRVD_TRIGGER_CHANGE) == 0)
+ {
+ return OC_PRESENCE_TRIGGER_CHANGE;
+ }
+ else
+ {
+ return OC_PRESENCE_TRIGGER_DELETE;
}
- *maxAge = (uint32_t) atoi(tok);
+}
- //Retrieve ResourceType
- tok = strtok_r(NULL, "[:]}",&savePtr);
- if(tok == NULL)
+void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge,
+ OCPresenceTrigger *presenceTrigger, char** resType)
+{
+ if(!payload || !seqNum || !maxAge || !presenceTrigger || !resType)
{
return;
}
- *resType = (char *)OCMalloc(strlen(tok) + 1);
- if(!*resType)
+ cJSON *repObj = cJSON_Parse(payload);
+ cJSON *ocObj = NULL;
+ cJSON *presenceObj = NULL;
+ cJSON *seqNumObj = NULL;
+ cJSON *maxAgeObj = NULL;
+ cJSON *triggerObj = NULL;
+ cJSON *resObj = NULL;
+ size_t size = 0;
+ if(repObj)
{
- return;
+ 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 = seqNumObj->valueint;
+ }
+ 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)
+ {
+ size = strlen(resObj->valuestring) + 1;
+ *resType = (char *)OCMalloc(size);
+ if(!*resType)
+ {
+ goto exit;
+ }
+ strncpy(*resType, resObj->valuestring, size);
+ }
+ 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."));
+ OCFree(*resType);
+ goto exit;
+ }
+ }
+ else
+ {
+ OC_LOG(ERROR, TAG, PCF("JSON Presence Payload does not contain a"
+ " valid \"oic\" JSON representation."));
+ OCFree(*resType);
+ goto exit;
+ }
+ }
+ else
+ {
+ OC_LOG(ERROR, TAG, PCF("JSON Presence Payload does map to a valid JSON"
+ " representation."));
+ OCFree(*resType);
+ goto exit;
}
- payload[strlen((char *)payload)] = ':';
- strcpy(*resType, tok);
- OC_LOG_V(DEBUG, TAG, "resourceTypeName %s", *resType);
- payload[strlen((char *)payload)] = ']';
+exit:
+ cJSON_Delete(repObj);
}
static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
OCDevAddr address = {};
OCStackResult result = OC_STACK_ERROR;
uint32_t maxAge = 0;
-
+ OCPresenceTrigger presenceTrigger = OC_PRESENCE_TRIGGER_CHANGE;
char *fullUri = NULL;
char *ipAddress = NULL;
int presenceSubscribe = 0;
goto exit;
}
- // No payload to the application in case of presence
- response.resJSONPayload = NULL;
+ response.resJSONPayload = responseInfo->info.payload;
response.result = OC_STACK_OK;
result = UpdateResponseAddr(&address, endPoint);
parsePresencePayload(responseInfo->info.payload,
&(response.sequenceNumber),
&maxAge,
+ &presenceTrigger,
&resourceTypeName);
}
ResetPresenceTTL(cbNode, maxAge);
- OC_LOG(INFO, TAG, PCF("Presence changed, calling up the stack"));
cbNode->sequenceNumber = response.sequenceNumber;
// Ensure that a filter is actually applied.
// a different random 32-bit integer number is used
((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
- return SendPresenceNotification(NULL);
+ return SendPresenceNotification(((OCResource *)presenceResource.handle)->rsrcType,
+ OC_PRESENCE_TRIGGER_CREATE);
}
OCStackResult OCStopPresence()
if(presenceResource.handle)
{
((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
- SendPresenceNotification(pointer->rsrcType);
+ SendPresenceNotification(pointer->rsrcType, OC_PRESENCE_TRIGGER_CREATE);
}
#endif
exit:
if(presenceResource.handle)
{
((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
- SendPresenceNotification(((OCResource *) resourceHandle)->rsrcType);
+ SendPresenceNotification(((OCResource *) resourceHandle)->rsrcType,
+ OC_PRESENCE_TRIGGER_CHANGE);
}
#endif
return OC_STACK_OK;
if(presenceResource.handle)
{
((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
- SendPresenceNotification(((OCResource *) resourceHandle)->rsrcType);
+ SendPresenceNotification(((OCResource *) resourceHandle)->rsrcType,
+ OC_PRESENCE_TRIGGER_CHANGE);
}
#endif
return OC_STACK_OK;
if(presenceResource.handle)
{
((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
- SendPresenceNotification(resource->rsrcType);
+ SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
}
#endif
if(presenceResource.handle)
{
((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
- SendPresenceNotification(resource->rsrcType);
+ SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
}
#endif
if(presenceResource.handle)
{
((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
- SendPresenceNotification(resource->rsrcType);
+ SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
}
#endif
}
#ifdef WITH_PRESENCE
-OCStackResult SendPresenceNotification(OCResourceType *resourceType)
+OCStackResult SendPresenceNotification(OCResourceType *resourceType,
+ OCPresenceTrigger trigger)
{
OCResource *resPtr = NULL;
OCStackResult result = OC_STACK_ERROR;
{
maxAge = presenceResource.presenceTTL;
- result = SendAllObserverNotification(method, resPtr, maxAge, resourceType, OC_LOW_QOS);
+ result = SendAllObserverNotification(method, resPtr, maxAge,
+ trigger, resourceType, OC_LOW_QOS);
}
return result;
}
// maxAge is 0. ResourceType is NULL.
- result = SendAllObserverNotification(method, resPtr, 0, NULL, OC_LOW_QOS);
+ result = SendAllObserverNotification(method, resPtr, 0, OC_PRESENCE_TRIGGER_DELETE,
+ NULL, OC_LOW_QOS);
return result;
}
method = OC_REST_OBSERVE;
maxAge = MAX_OBSERVE_AGE;
#ifdef WITH_PRESENCE
- result = SendAllObserverNotification (method, resPtr, maxAge, NULL, qos);
+ result = SendAllObserverNotification (method, resPtr, maxAge,
+ OC_PRESENCE_TRIGGER_DELETE, NULL, qos);
#else
result = SendAllObserverNotification (method, resPtr, maxAge, qos);
#endif
if(presenceResource.handle)
{
((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
- if(resource != (OCResource *) presenceResource.handle)
- {
- SendPresenceNotification(resource->rsrcType);
- }
- else
- {
- SendPresenceNotification(NULL);
- }
+ SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_DELETE);
}
#endif
// Only resource in list.
# Build flags
######################################################################
stacktest_env.PrependUnique(CPPPATH = [
+ '../../security/include',
'../../ocsocket/include',
'../../logger/include',
+ '../../ocrandom/include',
'../../stack/include',
+ '../../stack/include/internal',
+ '../../connectivity/api',
'../../ocmalloc/include',
'../../extlibs/cjson',
'../../../oc_logger/include',
extern "C"
{
#include "ocstack.h"
+ #include "ocstackinternal.h"
#include "logger.h"
#include "ocmalloc.h"
}
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
- void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge, char** resType);
+ void parsePresencePayload(char* payload, uint32_t* seqNum,
+ uint32_t* maxAge, OCPresenceTrigger* presenceTrigger, char** resType);
#ifdef __cplusplus
}
#endif // __cplusplus
char payload[100];
uint32_t seqNum = 0, maxAge = 0;
+ OCPresenceTrigger presenceTrigger = OC_PRESENCE_TRIGGER_CHANGE;
char * resType = NULL;
//Good Scenario
- strncpy(payload, "{\"oc\":[100:99:presence]}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &resType);
+ 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);
OCFree(resType);
+ presenceTrigger = OC_PRESENCE_TRIGGER_CHANGE;
+
//Bad Scenario -- should not result in Seg Fault
- parsePresencePayload(payload, NULL, &maxAge, &resType);
+ parsePresencePayload(payload, NULL, &maxAge, &presenceTrigger, &resType);
//Bad Scenario
seqNum = 0; maxAge = 0; resType = NULL;
strncpy(payload, "{abracadabra}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &resType);
+ 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);
OCFree(resType);
//Bad Scenario
seqNum = 0; maxAge = 0; resType = NULL;
- strncpy(payload, "{\"oc\":[100]}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &resType);
- EXPECT_TRUE(100 == seqNum);
+ 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);
OCFree(resType);
//Bad Scenario
seqNum = 0; maxAge = 0; resType = NULL;
- strncpy(payload, "{\"oc\":[]}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &resType);
+ 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);
OCFree(resType);
//Bad Scenario
strncpy(payload, "{:]}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &resType);
+ 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);
OCFree(resType);
//Bad Scenario
strncpy(payload, "{:[presence}", sizeof(payload));
- parsePresencePayload(payload, &seqNum, &maxAge, &resType);
+ 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);
OCFree(resType);
}