monitor: resource: Add timestamp support 53/273653/4
authorDongwoo Lee <dwoo08.lee@samsung.com>
Fri, 8 Apr 2022 03:04:08 +0000 (12:04 +0900)
committerDongwoo Lee <dwoo08.lee@samsung.com>
Wed, 13 Apr 2022 03:41:03 +0000 (03:41 +0000)
To provide timeline information of resource update, now provides
timestamp as start and end time of update. It is included in resource
json as "res_ts" with "start" and "end" object, and it also can be
retrieved with following new libpass function:
 - pass_resource_monitor_get_resource_timestamp()

Change-Id: Iad2cf8bb1d1100f4ded44ce5e19aeb119c65575e
Signed-off-by: Dongwoo Lee <dwoo08.lee@samsung.com>
include/util/request.h
include/util/resource.h
lib/resource-monitor/resource-monitor.c
lib/resource-monitor/resource-monitor.h
src/monitor/request-handler.c
src/util/resource.c

index fcee614..44d2047 100644 (file)
@@ -44,6 +44,7 @@ enum {
        REQUEST_GET_VALUE_DOUBLE,
        REQUEST_GET_VALUE_STRING,
        REQUEST_GET_VALUE_ARRAY,
+       REQUEST_GET_RESOURCE_TS,
        REQUEST_MAX,
 };
 
index 71d756f..97a1b93 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef __RESOURCE_H__
 #define __RESOURCE_H__
 
+#include <sys/time.h>
 #include <errno.h>
 #include <glib.h>
 #include "common.h"
@@ -136,6 +137,9 @@ struct resource {
        const struct resource_control *ctrls;
        u_int64_t attr_interest;
        u_int64_t attr_supported;
+
+       int64_t ts_start;
+       int64_t ts_end;
 };
 
 #define RESOURCE_DRIVER_REGISTER(resource_driver)      \
@@ -180,8 +184,9 @@ resource_attr_supported_always(const struct resource *resource,
 }
 
 int get_resource_attrs_json(struct resource *resource, char **json_string);
-
 int get_resource_attr_json(struct resource *resource, u_int64_t attr_id, char **json_string);
+int get_resource_list_json(char **json_string);
+
 int get_resource_attr_int(struct resource *resource, u_int64_t attr_id, int32_t *data);
 int get_resource_attr_int64(struct resource *resource, u_int64_t attr_id, int64_t *data);
 int get_resource_attr_uint(struct resource *resource, u_int64_t attr_id, u_int32_t *data);
@@ -194,4 +199,12 @@ int get_resource_attr_ptr(struct resource *resource, u_int64_t attr_id, void **d
 
 int set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask);
 int unset_resource_attr_interest(struct resource *resource, u_int64_t interest_mask);
+
+inline __attribute__((always_inline)) int64_t get_time_now(void)
+{
+       struct timeval tv;
+
+       gettimeofday(&tv, NULL);
+       return (int64_t)tv.tv_sec * 1000000 + (int64_t)tv.tv_usec;
+}
 #endif
index af25357..02361f9 100644 (file)
@@ -924,3 +924,35 @@ int pass_resource_monitor_get_array_string(int id, int res_id, u_int64_t attr_id
 {
        return pass_resource_monitor_get_array(id, res_id, attr_id, DATA_TYPE_STRING, (void **)array, length);
 }
+
+int pass_resource_monitor_get_resource_timestamp(int id, int res_id, int64_t *start, int64_t *end)
+{
+       char buffer[GENERIC_BUFF_MAX + 1];
+       int buffer_len;
+       int response_req;
+       int ret;
+
+       buffer_len = sprintf(buffer, "%d$%d", REQUEST_GET_RESOURCE_TS, res_id);
+       if (send(id, buffer, buffer_len, 0) < 0) {
+               _E("[libpass] error occurred while sending buffer");
+               return -EIO;
+       }
+
+       /* wait for response */
+       buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0);
+       if (buffer_len <= 0) {
+               _E("[libpass] socket disconnected");
+               return -EIO;
+       }
+       buffer[buffer_len] = '\0';
+
+       if (sscanf(buffer, "%d$%"PRId64"$%"PRId64"$%d", &response_req, start, end, &ret) < 3)
+               return -EINVAL;
+
+       if (response_req != REQUEST_GET_VALUE_INT64) {
+               _E("[libpass] wrong response");
+               return -EINVAL;
+       }
+
+       return ret;
+}
index 515ec10..c943dc4 100644 (file)
@@ -266,6 +266,17 @@ int pass_resource_monitor_get_array_uint64(int id, int res_id, u_int64_t attr, u
 int pass_resource_monitor_get_array_double(int id, int res_id, u_int64_t attr, double **array, int *length);
 int pass_resource_monitor_get_array_string(int id, int res_id, u_int64_t attr, char ***array, int *length);
 
+/**
+ * @brief Get timestamp of the latest resource update
+ * @param[in] Resource monitor id
+ * @param[in] Resource id
+ * @param[out] start time of update
+ * @param[out] end time of update
+ * @return @ 0 on success, otherwise a negative error value
+ */
+
+int pass_resource_monitor_get_resource_timestamp(int id, int res_id, int64_t *start, int64_t *end);
+
 #ifdef __cplusplus
 }
 #endif
index 3bbea40..2bad112 100644 (file)
@@ -454,6 +454,32 @@ handle_request_get_value_array(struct request_client *client, char *args, struct
        return get_resource_attr_array(res, attr_id, arr);
 }
 
+static int
+handle_request_get_resource_ts(struct request_client *client, char *args,
+                              int64_t *start, int64_t *end)
+{
+       struct resource *res;
+       int resource_id;
+
+       if (!client || !args)
+               return -ENOENT;
+
+       /**
+        * Format of REQUEST_GET_RESOURCE_TS args:
+        *  - <RESOURCE_ID>
+        */
+       resource_id = atoi(args);
+
+       res = get_resource_by_id(client, resource_id);
+       if (!res)
+               return -EINVAL;
+
+       *start = res->ts_start;
+       *end = res->ts_end;
+
+       return 0;
+}
+
 static int split_request_type_and_args(char *buffer, char **args)
 {
        char *request_type_str;
@@ -690,6 +716,17 @@ static int handle_request(struct request_client *client, char *request)
                        }
                }
                break;
+       case REQUEST_GET_RESOURCE_TS:
+               {
+                       int64_t start, end;
+
+                       ret = handle_request_get_resource_ts(client, args, &start, &end);
+                       if (ret < 0)
+                               _D("failed to get value");
+
+                       ADD_RESPONSE(response, buffer_len, "%"PRId64"$%"PRId64"$", start, end);
+               }
+               break;
        default:
                _E("Invliad request type: %d", request_type);
                ret = -EINVAL;
index aefe3cc..abe7b49 100644 (file)
@@ -254,6 +254,8 @@ int update_resource_attrs(struct resource *resource)
        if (!resource || !resource->type)
                return -EINVAL;
 
+       resource->ts_start = get_time_now();
+
        if (resource->driver && resource->driver->ops.prepare_update) {
                ret = resource->driver->ops.prepare_update(resource);
                if (ret < 0)
@@ -270,6 +272,8 @@ int update_resource_attrs(struct resource *resource)
                }
        }
 
+       resource->ts_end = get_time_now();
+
        return 0;
 }
 
@@ -468,6 +472,7 @@ static void _put_resource_attr_json(json_object *jobj_attr)
 int get_resource_attrs_json(struct resource *resource, char **json_string)
 {
        json_object *jobj_root, *jobj_res_name, *jobj_res_type, *jobj_res_attrs, *jobj_attr;
+       json_object *jobj_res_ts, *jobj_ts_start, *jobj_ts_end;
        const struct resource_attribute *attr;
        const struct resource_attribute_value *attr_value;
        int i;
@@ -493,18 +498,30 @@ int get_resource_attrs_json(struct resource *resource, char **json_string)
                json_object_array_add(jobj_res_attrs, jobj_attr);
        }
 
+       jobj_res_ts = json_object_new_object();
+       jobj_ts_start = json_object_new_int64(resource->ts_start);
+       jobj_ts_end = json_object_new_int64(resource->ts_end);
+
+       json_object_object_add(jobj_res_ts, "start", jobj_ts_start);
+       json_object_object_add(jobj_res_ts, "end", jobj_ts_end);
+
        json_object_object_add(jobj_root, "res_name", jobj_res_name);
        json_object_object_add(jobj_root, "res_type", jobj_res_type);
        json_object_object_add(jobj_root, "res_attrs", jobj_res_attrs);
+       json_object_object_add(jobj_root, "res_ts", jobj_res_ts);
 
        *json_string = strdup(json_object_to_json_string(jobj_root));
 
+       json_object_object_del(jobj_res_ts, "end");
+       json_object_object_del(jobj_res_ts, "start");
+
        for (i = 0; i < json_object_array_length(jobj_res_attrs); i++) {
                jobj_attr = json_object_array_get_idx(jobj_res_attrs, i);
                _put_resource_attr_json(jobj_attr);
        }
        json_object_array_del_idx(jobj_res_attrs, 0, json_object_array_length(jobj_res_attrs));
 
+       json_object_object_del(jobj_root, "res_ts");
        json_object_object_del(jobj_root, "res_attrs");
        json_object_object_del(jobj_root, "res_type");
        json_object_object_del(jobj_root, "res_name");