--- /dev/null
+/*
+ * faultd
+ *
+ * Copyright © 2017 Samsung Electronics
+ *
+ * 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 <errno.h>
+
+#include "event.h"
+#include "module.h"
+#include "common.h"
+
+struct event_factory {
+ struct faultd_module module;
+ struct list_head types;
+};
+
+#define to_event_factory(MOD) \
+ container_of(MOD, struct event_factory, module)
+
+static int init_event_factory(struct faultd_module *module,
+ sd_event *event_loop)
+{
+ return 0;
+}
+
+static void cleanup_event_factory(struct faultd_module *module)
+{
+ struct event_factory *efactory = to_event_factory(module);
+
+ assert(list_empty(&efactory->types));
+}
+
+static struct event_factory event_factory = {
+ .module = {
+ .name = "event_factory",
+ .type = FAULTD_MODULE_TYPE_CORE,
+
+ .init = init_event_factory,
+ .cleanup = cleanup_event_factory,
+ .node = LIST_HEAD_INIT(event_factory.module.node),
+ },
+ .types = LIST_HEAD_INIT(event_factory.types),
+};
+
+FAULTD_MODULE_REGISTER(&event_factory.module);
+
+int faultd_event_type_register(struct faultd_event_type *new)
+{
+ if (!new->name || !new->allocate_event)
+ return -EINVAL;
+
+ list_add_tail(&new->node, &event_factory.types);
+
+ return 0;
+}
+
+void faultd_event_type_unregister(struct faultd_event_type *type)
+{
+ if (list_empty(&type->node))
+ return;
+
+ list_del_init(&type->node);
+}
+
+int faultd_event_create(const char *type, void *data, struct faultd_event **ev)
+{
+ struct faultd_event_type *ev_type;
+ int ret;
+
+ if (!type)
+ return -EINVAL;
+
+ list_for_each_entry(ev_type, &event_factory.types, node)
+ if (strcmp(ev_type->name, type) == 0)
+ break;
+ if (&ev_type->node == &event_factory.types)
+ return -ENOENT;
+
+ ret = ev_type->allocate_event(ev_type, data, ev);
+
+ return ret;
+}
+
+static void release_faultd_event(struct uref *uref)
+{
+ struct faultd_event *ev = container_of(uref, struct faultd_event, uref);
+
+ if (ev->ops.release)
+ ev->ops.release(ev);
+}
+
+int faultd_event_init(struct faultd_event_type *ev_type,
+ struct faultd_event *ev)
+{
+ int ret;
+
+ ret = clock_gettime(CLOCK_MONOTONIC, &ev->timestamp);
+ if (ret)
+ return ret;
+
+ ev->type = ev_type;
+ ev->ops = ev_type->default_ops;
+
+ uref_init(&ev->uref, release_faultd_event);
+ INIT_LIST_HEAD(&ev->node);
+ INIT_NQUEUE_NODE(&ev->nq_node);
+
+ return 0;
+}
--- /dev/null
+/*
+ * faultd
+ *
+ * Copyright © 2017 Samsung Electronics
+ *
+ * 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 FAULTD_EVENT_H
+#define FAULTD_EVENT_H
+
+#include <time.h>
+#include <string.h>
+
+#include "uref.h"
+#include "list.h"
+#include "notify_queue.h"
+#include "module.h"
+
+struct faultd_event;
+
+struct faultd_event_ops {
+ char *(*to_string)(struct faultd_event *);
+ void (*release)(struct faultd_event *);
+};
+
+struct faultd_event_type {
+ char *name;
+
+ struct faultd_event_ops default_ops;
+
+ /* Add function to allocate event from DB */
+
+ /* Allocate event based on passed data */
+ int (*allocate_event)(struct faultd_event_type *type,
+ void *data, struct faultd_event **);
+
+ /* To be used by event factory */
+ struct list_head node;
+};
+
+struct faultd_event {
+ struct timespec timestamp;
+
+ /* TODO: add here some id field */
+
+ struct faultd_event_type *type;
+ struct faultd_event_ops ops;
+
+ struct uref uref;
+ /* To be used by event holder */
+ struct list_head node;
+ /* To be used by event processig FW */
+ struct nqueue_node nq_node;
+};
+
+int faultd_event_type_register(struct faultd_event_type *type);
+void faultd_event_type_unregister(struct faultd_event_type *type);
+
+#define FAULTD_EVENT_TYPE_REGISTER(EVENT_TYPE, NAME) \
+static int event_type_ ##NAME## _init(struct faultd_module *module, \
+ sd_event *event_loop) \
+{ \
+ return faultd_event_type_register(&EVENT_TYPE); \
+} \
+ \
+static void event_type_ ##NAME## _cleanup(struct faultd_module *module) \
+{ \
+ faultd_event_type_unregister(&EVENT_TYPE); \
+} \
+ \
+static struct faultd_module event_type_ ##NAME## _module = { \
+ .name = #NAME, \
+ .type = FAULTD_MODULE_TYPE_EVENT, \
+ .init = event_type_ ##NAME## _init, \
+ .cleanup = event_type_ ##NAME## _cleanup, \
+ .node = LIST_HEAD_INIT(event_type_ ##NAME## _module.node), \
+}; \
+ \
+FAULTD_MODULE_REGISTER(&event_type_ ##NAME## _module)
+
+int faultd_event_create(const char *type, void *data, struct faultd_event **ev);
+
+static inline void faultd_event_ref(struct faultd_event *ev)
+{
+ uref_get(&ev->uref);
+}
+
+static inline void faultd_event_unref(struct faultd_event *ev)
+{
+ uref_put(&ev->uref);
+}
+
+static inline int faultd_event_is_of_type(struct faultd_event *ev,
+ const char *type)
+{
+ return strcmp(ev->type->name, type) == 0;
+}
+
+static inline char *faultd_event_to_string(struct faultd_event *ev)
+{
+ return ev->ops.to_string(ev);
+}
+
+int faultd_event_init(struct faultd_event_type *ev_type,
+ struct faultd_event *ev);
+
+static inline void faultd_event_cleanup(struct faultd_event *ev) {}
+
+#endif /* FAULTD_EVENT_H */