+int connman_element_add_static_property(struct connman_element *element,
+ const char *name, int type, const void *value)
+{
+ struct connman_property *property;
+
+ DBG("element %p name %s", element, element->name);
+
+ if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
+ return -EINVAL;
+
+ property = g_try_new0(struct connman_property, 1);
+ if (property == NULL)
+ return -ENOMEM;
+
+ property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
+ property->id = CONNMAN_PROPERTY_ID_INVALID;
+ property->name = g_strdup(name);
+ property->type = type;
+
+ DBG("name %s type %d value %p", name, type, value);
+
+ switch (type) {
+ case DBUS_TYPE_STRING:
+ property->value = g_strdup(*((const char **) value));
+ break;
+ case DBUS_TYPE_BYTE:
+ property->value = g_try_malloc(1);
+ if (property->value != NULL)
+ memcpy(property->value, value, 1);
+ break;
+ }
+
+ __connman_element_lock(element);
+ element->properties = g_slist_append(element->properties, property);
+ __connman_element_unlock(element);
+
+ return 0;
+}
+
+int connman_element_add_static_array_property(struct connman_element *element,
+ const char *name, int type, const void *value, int len)
+{
+ struct connman_property *property;
+
+ DBG("element %p name %s", element, element->name);
+
+ if (type != DBUS_TYPE_BYTE)
+ return -EINVAL;
+
+ property = g_try_new0(struct connman_property, 1);
+ if (property == NULL)
+ return -ENOMEM;
+
+ property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
+ property->id = CONNMAN_PROPERTY_ID_INVALID;
+ property->name = g_strdup(name);
+ property->type = DBUS_TYPE_ARRAY;
+ property->subtype = type;
+
+ DBG("name %s type %d value %p", name, type, value);
+
+ switch (type) {
+ case DBUS_TYPE_BYTE:
+ property->value = g_try_malloc(len);
+ if (property->value != NULL) {
+ memcpy(property->value,
+ *((const unsigned char **) value), len);
+ property->size = len;
+ }
+ break;
+ }
+
+ __connman_element_lock(element);
+ element->properties = g_slist_append(element->properties, property);
+ __connman_element_unlock(element);
+
+ return 0;
+}
+
+static void *get_reference_value(struct connman_element *element,
+ enum connman_property_id id)
+{
+ GSList *list;
+
+ DBG("element %p name %s", element, element->name);
+
+ for (list = element->properties; list; list = list->next) {
+ struct connman_property *property = list->data;
+
+ if (property->id != id)
+ continue;
+
+ if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
+ return property->value;
+ }
+
+ if (element->parent == NULL)
+ return NULL;
+
+ return get_reference_value(element->parent, id);
+}
+
+static void set_reference_properties(struct connman_element *element)
+{
+ GSList *list;
+
+ DBG("element %p name %s", element, element->name);
+
+ for (list = element->properties; list; list = list->next) {
+ struct connman_property *property = list->data;
+
+ if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
+ continue;
+
+ property->value = get_reference_value(element->parent,
+ property->id);
+ }
+}
+
+static struct connman_property *create_property(struct connman_element *element,
+ enum connman_property_id id)
+{
+ struct connman_property *property;
+ GSList *list;
+
+ DBG("element %p name %s", element, element->name);
+
+ __connman_element_lock(element);
+
+ for (list = element->properties; list; list = list->next) {
+ property = list->data;
+
+ if (property->id == id)
+ goto unlock;
+ }
+
+ property = g_try_new0(struct connman_property, 1);
+ if (property == NULL)
+ goto unlock;
+
+ property->flags = CONNMAN_PROPERTY_FLAG_REFERENCE;
+ property->id = id;
+ property->name = g_strdup(propid2name(id));
+ property->type = propid2type(id);
+
+ if (property->name == NULL) {
+ g_free(property);
+ property = NULL;
+ goto unlock;
+ }
+
+ element->properties = g_slist_append(element->properties, property);
+
+unlock:
+ __connman_element_unlock(element);
+
+ return property;
+}
+
+static void create_default_properties(struct connman_element *element)
+{
+ struct connman_property *property;
+ int i;
+
+ DBG("element %p name %s", element, element->name);
+
+ for (i = 0; propid_table[i].name; i++) {
+ DBG("property %s", propid_table[i].name);
+
+ property = create_property(element, propid_table[i].id);
+
+ property->flags &= ~CONNMAN_PROPERTY_FLAG_REFERENCE;
+
+ if (propid_table[i].type != DBUS_TYPE_STRING)
+ continue;
+
+ if (propid_table[i].value)
+ property->value = g_strdup(propid_table[i].value);
+ else
+ property->value = g_strdup("");
+ }
+}
+
+static int define_properties_valist(struct connman_element *element,
+ va_list args)
+{
+ enum connman_property_id id;
+
+ DBG("element %p name %s", element, element->name);
+
+ id = va_arg(args, enum connman_property_id);
+
+ while (id != CONNMAN_PROPERTY_ID_INVALID) {
+
+ DBG("property %d", id);
+
+ create_property(element, id);
+
+ id = va_arg(args, enum connman_property_id);
+ }
+
+ return 0;
+}
+
+/**
+ * connman_element_define_properties:
+ * @element: an element
+ * @varargs: list of property identifiers
+ *
+ * Define the valid properties for an element.
+ *
+ * Returns: %0 on success
+ */
+int connman_element_define_properties(struct connman_element *element, ...)