--- /dev/null
+/*
+ * PASS
+ *
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __RESOURCE_H__
+#define __RESOURCE_H__
+
+#include <errno.h>
+#include <glib.h>
+#include "common.h"
+
+struct resource;
+struct resource_attribute;
+
+struct resource_attribute_value {
+ /* Indicate the data type among three types (int/double/str)*/
+ int type;
+
+ union {
+ /* Have to use only one among the types */
+ int int_value;
+
+ int number_int;
+ int *int_values;
+
+ double double_value;
+
+ int number_string;
+ char *str_value;;
+ } data;
+};
+
+struct resource_attribute_ops {
+ int (*set)(const struct resource *res,
+ const struct resource_attribute *attr,
+ const char *buf, int count, void *user_data);
+ int (*get)(const struct resource *res,
+ const struct resource_attribute *attr,
+ char *buf, void *user_data);
+};
+
+struct resource_attribute {
+ const char name[BUFF_MAX];
+ const uint32 id;
+ const int type;
+ const struct resource_attribute_ops ops;
+};
+
+struct resource_driver {
+ const char *name;
+ const int type;
+ const int num_attrs;
+ const struct resource_attribute *attrs;
+};
+
+struct resource {
+ char *name;
+ int type;
+ void *user_data;
+
+ int num_attrs;
+ const struct resource_attribute *attrs;
+ struct resource_attribute_value *attrs_value;
+};
+
+#define RESOURCE_DRIVER_REGISTER(resource_driver) \
+static void __CONSTRUCTOR__ module_init(void) \
+{ \
+ add_resource_driver(resource_driver); \
+} \
+static void __DESTRUCTOR__ module_exit(void) \
+{ \
+ remove_resource_driver(resource_driver); \
+}
+
+void add_resource_driver(const struct resource_driver *resource_driver);
+void remove_resource_driver(const struct resource_driver *resource_driver);
+
+struct resource *create_resource(int resource_type, const char *resource_name, void *user_data);
+void delete_resource(struct resource *resource);
+
+int update_resource_attr(struct resource *resource, int attr_id);
+int update_resource_attrs(struct resource *resource);
+struct resource_attribute_value *get_resource_attr_value(struct resource *resource, int attr_id);
+int get_resource_attr_integer(struct resource *resource, int attr_id);
+int get_resource_attr_integer_sync(struct resource *resource, int attr_id);
+
+#endif
--- /dev/null
+/*
+ * PASS (Power Aware System Service)
+ *
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <stdio.h>
+
+#include <util/common.h>
+#include <util/resource.h>
+#include <util/log.h>
+
+#include <monitor/monitor.h>
+
+static GList *g_resource_driver_head;
+
+static gint __compare_resource_type(gconstpointer data, gconstpointer input)
+{
+ struct resource_driver *driver = (struct resource_driver *)data;
+ int type = *(int *)input;
+
+ if (driver->type == type)
+ return 0;
+ return -1;
+}
+
+void add_resource_driver(const struct resource_driver *driver)
+{
+ if (!driver)
+ return;
+
+ g_resource_driver_head =
+ g_list_append(g_resource_driver_head, (gpointer)driver);
+}
+
+void remove_resource_driver(const struct resource_driver *driver)
+{
+ if (!driver)
+ return;
+
+ g_resource_driver_head =
+ g_list_remove(g_resource_driver_head, (gpointer)driver);
+}
+
+const struct resource_driver *get_resource_driver(int resource_type)
+{
+ GList *node;
+
+ node = g_list_find_custom(g_resource_driver_head,
+ &resource_type, __compare_resource_type);
+
+ if (!node)
+ return NULL;
+ return (struct resource_driver *)node->data;
+}
+
+void delete_resource(struct resource *resource)
+{
+ if (!resource)
+ return;
+
+ if (!resource->name)
+ free(resource->name);
+ if (!resource->attrs_value)
+ free(resource->attrs_value);
+ resource->attrs = NULL;
+ resource->num_attrs = 0;
+
+ free(resource);
+}
+
+struct resource *create_resource(int resource_type, const char *resource_name, void *user_data)
+{
+ const struct resource_driver *driver = NULL;
+ struct resource *resource = NULL;
+ int i;
+
+ driver = get_resource_driver(resource_type);
+ if (!driver)
+ return NULL;
+
+ resource = calloc(1, sizeof(*resource));
+ if (!resource)
+ return NULL;
+
+ resource->type = resource_type;
+ resource->name = g_strdup(resource_name);
+ resource->user_data = user_data;
+ resource->num_attrs = driver->num_attrs;
+ resource->attrs = driver->attrs;
+ resource->attrs_value = calloc(resource->num_attrs,
+ sizeof(*resource->attrs_value));
+ if (!resource->attrs_value) {
+ delete_resource(resource);
+ return NULL;
+ }
+
+ for (i = 0; i < resource->num_attrs; i++)
+ resource->attrs_value[i].type = driver->attrs[i].type;
+
+ return resource;
+}
+
+int update_resource_attr(struct resource *resource, int attr_id)
+{
+ int resource_type = RESOURCE_TYPE(attr_id);
+ int attr_index = RESOURCE_ATTR_INDEX(attr_id);
+ const struct resource_attribute *attr = NULL;
+ struct resource_attribute_value *attr_value = NULL;
+ char buf[BUFF_MAX];
+ int ret;
+
+ if (!resource || resource->type != resource_type)
+ return -EINVAL;
+
+ if (attr_index < 0 || attr_index >= resource->num_attrs)
+ return -EINVAL;
+
+ attr = &resource->attrs[attr_index];
+ attr_value = &resource->attrs_value[attr_index];
+
+ if (!attr->ops.get)
+ return -EINVAL;
+
+ ret = attr->ops.get(resource, attr, buf, resource->user_data);
+ if (ret < 0)
+ return ret;
+
+ /* FIXME: Need to be changed according to data type*/
+ ret = sscanf(buf, "%d", &(attr_value->data.int_value));
+ if (ret != 1)
+ return -EINVAL;
+
+ return 0;
+}
+
+int update_resource_attrs(struct resource *resource)
+{
+ int i, ret;
+
+ if (!resource || !resource->type)
+ return -EINVAL;
+
+ for (i = 0; i < resource->num_attrs; i++) {
+ ret = update_resource_attr(resource, resource->attrs[i].id);
+ if (ret < 0) {
+ _E("failed to update resource attr \n");
+ }
+ }
+
+ return 0;
+}
+
+struct resource_attribute_value *
+get_resource_attr_value(struct resource *resource, int attr_id)
+{
+ int attr_index = RESOURCE_ATTR_INDEX(attr_id);
+
+ if (!resource || resource->type != RESOURCE_TYPE(attr_id))
+ return NULL;
+
+ if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
+ return NULL;
+
+ return &resource->attrs_value[attr_index];
+}
+
+int get_resource_attr_integer(struct resource *resource, int attr_id)
+{
+ struct resource_attribute_value *attr_value =
+ get_resource_attr_value(resource, attr_id);
+
+ if (!attr_value)
+ return -EINVAL;
+
+ return attr_value->data.int_value;
+}
+
+int get_resource_attr_integer_sync(struct resource *resource, int attr_id)
+{
+ int ret;
+
+ ret = update_resource_attr(resource, attr_id);
+ if (ret < 0)
+ return ret;
+
+ return get_resource_attr_integer(resource, attr_id);
+}