REQUEST_GET_VALUE_DOUBLE,
REQUEST_GET_VALUE_STRING,
REQUEST_GET_VALUE_ARRAY,
+ REQUEST_GET_RESOURCE_TS,
REQUEST_MAX,
};
#ifndef __RESOURCE_H__
#define __RESOURCE_H__
+#include <sys/time.h>
#include <errno.h>
#include <glib.h>
#include "common.h"
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) \
}
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);
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
{
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;
+}
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
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;
}
}
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;
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)
}
}
+ resource->ts_end = get_time_now();
+
return 0;
}
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;
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");