Converting OTA payload for advertisements to JSON packaging.
[contrib/iotivity.git] / resource / csdk / stack / src / ocobserve.c
index 654078d..ff573bd 100644 (file)
@@ -27,6 +27,7 @@
 #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.
@@ -95,7 +169,7 @@ static OCQualityOfService DetermineObserverQoS(OCMethod method,
 
 #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)
@@ -174,25 +248,24 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
 
                 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