modify "is_observable->properties", & remove tizen_info
[platform/core/iot/iotcon.git] / daemon / icd-payload.c
index 471baac..008b544 100644 (file)
@@ -25,6 +25,8 @@
 #include "iotcon.h"
 #include "ic-utils.h"
 #include "icd.h"
+#include "icd-ioty.h"
+#include "icd-ioty-type.h"
 #include "icd-payload.h"
 
 union icd_state_value_u {
@@ -40,6 +42,8 @@ struct icd_state_list_s {
 };
 
 static GVariant* _icd_payload_representation_to_gvariant(OCRepPayload *repr, gboolean is_parent);
+static void _icd_state_value_from_gvariant(OCRepPayload *repr, GVariantIter *iter);
+static GVariantBuilder* _icd_state_value_to_gvariant_builder(OCRepPayload *repr);
 
 GVariant** icd_payload_res_to_gvariant(OCPayload *payload, OCDevAddr *dev_addr)
 {
@@ -51,9 +55,9 @@ GVariant** icd_payload_res_to_gvariant(OCPayload *payload, OCDevAddr *dev_addr)
        GVariantBuilder types;
        OCRandomUuidResult random_res;
        OCDiscoveryPayload *discovered;
-       char sid[UUID_STRING_SIZE] = {0};
        struct OCResourcePayload *resource;
-       int i, is_observable, ret, res_count;
+       int i, properties, ret, res_count;
+       char device_id[UUID_STRING_SIZE] = {0};
 
        discovered = (OCDiscoveryPayload*)payload;
        resource = discovered->resources;
@@ -72,8 +76,8 @@ GVariant** icd_payload_res_to_gvariant(OCPayload *payload, OCDevAddr *dev_addr)
                        resource = resource->next;
                }
 
-               /* sid */
-               random_res = OCConvertUuidToString(resource->sid, sid);
+               /* device id */
+               random_res = OCConvertUuidToString(resource->sid, device_id);
                if (RAND_UUID_OK != random_res) {
                        ERR("OCConvertUuidToString() Fail(%d)", random_res);
                        resource = resource->next;
@@ -108,14 +112,16 @@ GVariant** icd_payload_res_to_gvariant(OCPayload *payload, OCDevAddr *dev_addr)
                        node = node->next;
                }
 
-               /* is_observable */
-               is_observable = resource->bitmap & OC_OBSERVABLE;
+               /* Resource Properties */
+               properties = icd_ioty_oic_properties_to_properties(resource->bitmap);
 
                /* port */
                port = (resource->port)? resource->port:dev_addr->port;
 
-               value[i] = g_variant_new("(ssiasibsi)", resource->uri, sid, ifaces, &types,
-                               is_observable, resource->secure, dev_addr->addr, port);
+               /* TODO
+                * Check "resource->secure" and "resource->bitmap" */
+               value[i] = g_variant_new("(ssiasibsi)", resource->uri, device_id, ifaces, &types,
+                               properties, resource->secure, dev_addr->addr, port);
                DBG("found resource[%d] : %s", i, g_variant_print(value[i], FALSE));
 
                resource = resource->next;
@@ -157,7 +163,8 @@ static GVariant* _icd_state_array_attr_to_gvariant(OCRepPayloadValueArray *arr,
                break;
        case OCREP_PROP_OBJECT:
                for (i = 0; i < len; i++) {
-                       var = _icd_payload_representation_to_gvariant(arr->objArray[index + i], TRUE);
+                       GVariantBuilder *state_var = _icd_state_value_to_gvariant_builder(arr->objArray[index + i]);
+                       var = g_variant_builder_end(state_var);
                        g_variant_builder_add(&builder, "v", var);
                }
                break;
@@ -196,8 +203,18 @@ static GVariant* _icd_state_array_to_gvariant(OCRepPayloadValueArray *arr,
        return g_variant_builder_end(&builder);
 }
 
+static GVariant* _icd_state_value_to_gvariant(OCRepPayload *state)
+{
+       GVariantBuilder *builder;
+       GVariant *var;
+
+       builder = _icd_state_value_to_gvariant_builder(state);
+       var = g_variant_builder_end(builder);
+
+       return var;
+}
 
-static GVariantBuilder* _icd_state_value_to_gvariant(OCRepPayload *repr)
+static GVariantBuilder* _icd_state_value_to_gvariant_builder(OCRepPayload *repr)
 {
        int total_len;
        GVariant *var = NULL;
@@ -228,7 +245,7 @@ static GVariantBuilder* _icd_state_value_to_gvariant(OCRepPayload *repr)
                        var = _icd_state_array_to_gvariant(&(val->arr), 0, total_len, 0);
                        break;
                case OCREP_PROP_OBJECT:
-                       var = _icd_payload_representation_to_gvariant(val->obj, TRUE);
+                       var = _icd_state_value_to_gvariant(val->obj);
                        break;
                default:
                        ERR("Invalid Type");
@@ -244,7 +261,8 @@ static GVariantBuilder* _icd_state_value_to_gvariant(OCRepPayload *repr)
 }
 
 
-static GVariant* _icd_payload_representation_to_gvariant(OCRepPayload *repr, gboolean is_parent)
+static GVariant* _icd_payload_representation_to_gvariant(OCRepPayload *repr,
+               gboolean is_parent)
 {
        OCStringLL *node;
        int ret, ifaces = 0;
@@ -279,7 +297,7 @@ static GVariant* _icd_payload_representation_to_gvariant(OCRepPayload *repr, gbo
        }
 
        /* Representation */
-       repr_gvar = _icd_state_value_to_gvariant(repr);
+       repr_gvar = _icd_state_value_to_gvariant_builder(repr);
 
        /* Children */
        g_variant_builder_init(&children, G_VARIANT_TYPE("av"));
@@ -299,6 +317,21 @@ static GVariant* _icd_payload_representation_to_gvariant(OCRepPayload *repr, gbo
 }
 
 
+GVariant* icd_payload_representation_empty_gvariant(void)
+{
+       GVariant *value;
+       GVariantBuilder types, repr, children;
+
+       g_variant_builder_init(&types, G_VARIANT_TYPE("as"));
+       g_variant_builder_init(&repr, G_VARIANT_TYPE("a{sv}"));
+       g_variant_builder_init(&children, G_VARIANT_TYPE("av"));
+
+       value = g_variant_new("(siasa{sv}av)", IC_STR_NULL, 0, &types, &repr, &children);
+
+       return value;
+}
+
+
 static GVariant* _icd_payload_platform_to_gvariant(OCPlatformPayload *repr)
 {
        GVariant *value;
@@ -307,15 +340,15 @@ static GVariant* _icd_payload_platform_to_gvariant(OCPlatformPayload *repr)
                        repr->uri,
                        repr->info.platformID,
                        repr->info.manufacturerName,
-                       repr->info.manufacturerUrl,
-                       repr->info.modelNumber,
-                       repr->info.dateOfManufacture,
-                       repr->info.platformVersion,
-                       repr->info.operatingSystemVersion,
-                       repr->info.hardwareVersion,
-                       repr->info.firmwareVersion,
-                       repr->info.supportUrl,
-                       repr->info.systemTime);
+                       ic_utils_dbus_encode_str(repr->info.manufacturerUrl),
+                       ic_utils_dbus_encode_str(repr->info.modelNumber),
+                       ic_utils_dbus_encode_str(repr->info.dateOfManufacture),
+                       ic_utils_dbus_encode_str(repr->info.platformVersion),
+                       ic_utils_dbus_encode_str(repr->info.operatingSystemVersion),
+                       ic_utils_dbus_encode_str(repr->info.hardwareVersion),
+                       ic_utils_dbus_encode_str(repr->info.firmwareVersion),
+                       ic_utils_dbus_encode_str(repr->info.supportUrl),
+                       ic_utils_dbus_encode_str(repr->info.systemTime));
 
        return value;
 }
@@ -325,16 +358,16 @@ static GVariant* _icd_payload_device_to_gvariant(OCDevicePayload *repr)
 {
        GVariant *value;
        OCRandomUuidResult random_res;
-       char sid[UUID_STRING_SIZE] = {0};
+       char device_id[UUID_STRING_SIZE] = {0};
 
-       random_res = OCConvertUuidToString(repr->sid, sid);
+       random_res = OCConvertUuidToString(repr->sid, device_id);
        if (RAND_UUID_OK != random_res) {
                ERR("OCConvertUuidToString() Fail(%d)", random_res);
                return NULL;
        }
 
-       value = g_variant_new("(ssss)", repr->deviceName, sid, repr->specVersion,
-                       repr->dataModelVersion);
+       value = g_variant_new("(sssss)", repr->uri, repr->deviceName, repr->specVersion,
+                       device_id, repr->dataModelVersion);
 
        return value;
 }
@@ -424,15 +457,16 @@ static void _icd_state_list_from_gvariant(GVariant *var,
                        value_list->list = g_list_append(value_list->list, s);
        } else if (g_variant_type_equal(G_VARIANT_TYPE("av"), type)) {
                GVariant *value;
-
                if (g_variant_iter_loop(&iter, "v", &value)) {
-                       if (g_variant_is_of_type(value, G_VARIANT_TYPE("(siasa{sv}av)"))) {
-                               OCRepPayload *repr_value;
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE("a{sv}"))) {
+                               OCRepPayload *repr;
+                               GVariantIter state_iter;
                                value_list->type = OCREP_PROP_OBJECT;
                                do {
-                                       repr_value = icd_payload_representation_from_gvariant(value);
-                                       value_list->list = g_list_append(value_list->list, repr_value);
-
+                                       repr = OCRepPayloadCreate();
+                                       g_variant_iter_init(&state_iter, value);
+                                       _icd_state_value_from_gvariant(repr, &state_iter);
+                                       value_list->list = g_list_append(value_list->list, repr);
                                } while (g_variant_iter_loop(&iter, "v", &value));
 
                        } else if (g_variant_is_of_type(value, G_VARIANT_TYPE_ARRAY)) {
@@ -537,7 +571,6 @@ static void _icd_state_array_from_list(OCRepPayload *repr,
        }
 }
 
-
 static void _icd_state_value_from_gvariant(OCRepPayload *repr, GVariantIter *iter)
 {
        char *key;
@@ -564,21 +597,26 @@ static void _icd_state_value_from_gvariant(OCRepPayload *repr, GVariantIter *ite
                        else
                                OCRepPayloadSetPropString(repr, key, str_value);
 
+               } else if (g_variant_is_of_type(var, G_VARIANT_TYPE ("a{sv}"))) {
+                       GVariantIter state_iter;
+                       repr_value = OCRepPayloadCreate();
+                       g_variant_iter_init(&state_iter, var);
+                       _icd_state_value_from_gvariant(repr_value, &state_iter);
+                       OCRepPayloadSetPropObjectAsOwner(repr, key, repr_value);
+
                } else if (g_variant_is_of_type(var, G_VARIANT_TYPE_ARRAY)) {
                        memset(&value_list, 0, sizeof(struct icd_state_list_s));
                        _icd_state_list_from_gvariant(var, &value_list, 0);
                        _icd_state_array_from_list(repr, &value_list, key);
 
-               } else if (g_variant_is_of_type(var, G_VARIANT_TYPE("(siasa{sv}av)"))) {
-                       repr_value = icd_payload_representation_from_gvariant(var);
-                       OCRepPayloadSetPropObjectAsOwner(repr, key, repr_value);
+               } else {
+                       ERR("Invalid type(%s)", g_variant_get_type_string(var));
                }
        }
 
        return;
 }
 
-
 OCRepPayload* icd_payload_representation_from_gvariant(GVariant *var)
 {
        GVariant *child;
@@ -616,7 +654,289 @@ OCRepPayload* icd_payload_representation_from_gvariant(GVariant *var)
                cur->next = icd_payload_representation_from_gvariant(child);
                cur = cur->next;
        }
-
        return repr;
 }
 
+
+static int _oic_string_list_length(OCStringLL *str_list)
+{
+       int len = 0;
+
+       while (str_list) {
+               len++;
+               str_list = str_list->next;
+       }
+
+       return len;
+}
+
+
+static bool _oic_string_list_contain(OCStringLL *str_list, char *str_value)
+{
+       OCStringLL *c;
+
+       for (c = str_list; c; c = c->next) {
+               if (IC_STR_EQUAL == g_strcmp0(str_value, str_list->value))
+                       return true;
+       }
+
+       return false;
+}
+
+
+static int _representation_compare_string_list(OCStringLL *list1, OCStringLL *list2)
+{
+       OCStringLL *c;
+
+       if (NULL == list1 || NULL == list2)
+               return !!(list1 - list2);
+
+       if (_oic_string_list_length(list1) != _oic_string_list_length(list2))
+               return 1;
+
+       for (c = list1; c; c = c->next) {
+               if (false == _oic_string_list_contain(list2, c->value))
+                       return 1;
+       }
+
+       return IC_EQUAL;
+}
+
+
+static int _representation_compare_array(OCRepPayloadValueArray arr1,
+               OCRepPayloadValueArray arr2)
+{
+       int i, len1, len2;
+
+       len1 = calcDimTotal(arr1.dimensions);
+       len2 = calcDimTotal(arr2.dimensions);
+
+       if (len1 != len2)
+               return 1;
+
+       switch (arr1.type) {
+       case OCREP_PROP_INT:
+               for (i = 0; i < len1; i++) {
+                       if (arr1.iArray[i] != arr2.iArray[i])
+                               return 1;
+               }
+               break;
+       case OCREP_PROP_BOOL:
+               for (i = 0; i < len1; i++) {
+                       if (arr1.bArray[i] != arr2.bArray[i])
+                               return 1;
+               }
+               break;
+       case OCREP_PROP_DOUBLE:
+               for (i = 0; i < len1; i++) {
+                       if (arr1.dArray[i] != arr2.dArray[i])
+                               return 1;
+               }
+               break;
+       case OCREP_PROP_STRING:
+               for (i = 0; i < len1; i++) {
+                       if (IC_STR_EQUAL != g_strcmp0(arr1.strArray[i], arr2.strArray[i]))
+                               return 1;
+               }
+               break;
+       case OCREP_PROP_OBJECT:
+               for (i = 0; i < len1; i++) {
+                       if (IC_EQUAL != icd_payload_representation_compare(arr1.objArray[i],
+                                               arr2.objArray[i]))
+                               return 1;
+               }
+               break;
+       default:
+               ERR("Invalid Type (%d)", arr1.type);
+               return 1;
+       }
+
+       return IC_EQUAL;
+}
+
+
+static int _representation_compare_value(OCRepPayloadValue *value1,
+               OCRepPayloadValue *value2)
+{
+       int ret = 1;
+
+       if (NULL == value1 || NULL == value2)
+               return !!(value1 - value2);
+
+       /* compare key */
+       if (IC_STR_EQUAL != g_strcmp0(value1->name, value2->name))
+               return 1;
+
+       /* compare value */
+       if (value1->type != value2->type)
+               return 1;
+
+       switch (value1->type) {
+       case OCREP_PROP_NULL:
+               ret = IC_EQUAL;
+               break;
+       case OCREP_PROP_INT:
+               ret = (value1->i == value2->i)? IC_EQUAL : 1;
+               break;
+       case OCREP_PROP_DOUBLE:
+               ret = (value1->d == value2->d)? IC_EQUAL : 1;
+               break;
+       case OCREP_PROP_BOOL:
+               ret = (value1->b == value2->b)? IC_EQUAL : 1;
+               break;
+       case OCREP_PROP_STRING:
+               ret = (IC_STR_EQUAL == g_strcmp0(value1->str, value2->str))? IC_EQUAL : 1;
+               break;
+       case OCREP_PROP_OBJECT:
+               ret = icd_payload_representation_compare(value1->obj, value2->obj);
+               break;
+       case OCREP_PROP_ARRAY:
+               ret = _representation_compare_array(value1->arr, value2->arr);
+               break;
+       default:
+               ERR("Invalid Type (%d)", value1->type);
+       }
+
+       return ret;
+}
+
+
+static int _representation_values_list_length(OCRepPayloadValue *value_list)
+{
+       int len = 0;
+
+       while (value_list) {
+               len++;
+               value_list = value_list->next;
+       }
+
+       return len;
+}
+
+
+static bool _representation_values_list_contain(OCRepPayloadValue *value_list,
+               OCRepPayloadValue *value)
+{
+       OCRepPayloadValue *c;
+
+       for (c = value_list; c; c = c->next) {
+               if (IC_EQUAL == _representation_compare_value(c, value))
+                       return true;
+       }
+
+       return false;
+}
+
+
+static int _representation_compare_values_list(OCRepPayloadValue *value1,
+               OCRepPayloadValue *value2)
+{
+       OCRepPayloadValue *c;
+
+       if (NULL == value1 || NULL == value2)
+               return !!(value1 - value2);
+
+       if (_representation_values_list_length(value1)
+                       != _representation_values_list_length(value2))
+               return 1;
+
+       for (c = value1; c; c = c->next) {
+               if (false == _representation_values_list_contain(value2, c))
+                       return 1;
+       }
+
+       return IC_EQUAL;
+}
+
+
+static int _representation_compare_without_children(OCRepPayload *repr1,
+               OCRepPayload *repr2)
+{
+       int ret;
+
+       if (NULL == repr1 || NULL == repr2)
+               return !!(repr1 - repr2);
+
+       /* compare uri */
+       if (IC_STR_EQUAL != g_strcmp0(repr1->uri, repr2->uri))
+               return 1;
+
+       /* compare resource types */
+       ret = _representation_compare_string_list(repr1->types, repr2->types);
+       if (IC_EQUAL != ret)
+               return ret;
+
+       /* compare resource interfaces */
+       ret = _representation_compare_string_list(repr1->interfaces, repr2->interfaces);
+       if (IC_EQUAL != ret)
+               return ret;
+
+       /* compare values */
+       ret = _representation_compare_values_list(repr1->values, repr2->values);
+       if (IC_EQUAL != ret)
+               return ret;
+
+       return IC_EQUAL;
+}
+
+
+static int _representation_list_length(OCRepPayload *repr_list)
+{
+       int len = 0;
+
+       while (repr_list) {
+               len++;
+               repr_list = repr_list->next;
+       }
+
+       return len;
+}
+
+
+static bool _representation_list_contain(OCRepPayload *repr_list, OCRepPayload *repr)
+{
+       OCRepPayload *c;
+
+       for (c = repr_list; c; c = c->next) {
+               if (IC_EQUAL == _representation_compare_without_children(c, repr))
+                       return true;
+       }
+
+       return false;
+}
+
+
+static int _representation_compare_children(OCRepPayload *repr1, OCRepPayload *repr2)
+{
+       OCRepPayload *c;
+
+       if (NULL == repr1 || NULL == repr2)
+               return !!(repr1 - repr2);
+
+       if (_representation_list_length(repr1) != _representation_list_length(repr2))
+               return 1;
+
+       for (c = repr1; c; c = c->next) {
+               if (false == _representation_list_contain(repr2, c))
+                       return 1;
+       }
+
+       return IC_EQUAL;
+}
+
+
+int icd_payload_representation_compare(OCRepPayload *repr1, OCRepPayload *repr2)
+{
+       int ret;
+
+       ret = _representation_compare_without_children(repr1, repr2);
+       if (IC_EQUAL != ret)
+               return ret;
+
+       /* compare childrean */
+       ret = _representation_compare_children(repr1->next, repr2->next);
+       if (IC_EQUAL != ret)
+               return ret;
+
+       return IC_EQUAL;
+}