#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 {
};
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)
{
OCRandomUuidResult random_res;
OCDiscoveryPayload *discovered;
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;
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;
+ /* TODO
+ * Check "resource->secure" and "resource->bitmap" */
value[i] = g_variant_new("(ssiasibsi)", resource->uri, device_id, ifaces, &types,
- is_observable, resource->secure, dev_addr->addr, port);
+ properties, resource->secure, dev_addr->addr, port);
DBG("found resource[%d] : %s", i, g_variant_print(value[i], FALSE));
resource = resource->next;
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;
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;
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");
}
/* 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"));
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)) {
}
}
-
static void _icd_state_value_from_gvariant(OCRepPayload *repr, GVariantIter *iter)
{
char *key;
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;
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;
+}