summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-11-06 09:27:39 +0100
committerDavid Herrmann <dh.herrmann@gmail.com>2013-11-06 09:27:39 +0100
commit235ba3535b4417c4bdb967374934af6202f58c01 (patch)
treefc8cc8b96169b7ae87d152487efda61e512a4482
parent5b385427fa67e9c5d4f0f130ad5501cc027b37f7 (diff)
owfd: p2pd: add event-fn callbacks to interface
Allow external programs to register event-functions. We call these for all wpa events we get. This way, we can later add external dbus APIs or similar to allow clients to visualize our p2p events and add user interfaces. Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
-rw-r--r--src/p2pd.h12
-rw-r--r--src/p2pd_interface.c63
2 files changed, 75 insertions, 0 deletions
diff --git a/src/p2pd.h b/src/p2pd.h
index 2a57141..a76084c 100644
--- a/src/p2pd.h
+++ b/src/p2pd.h
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <sys/epoll.h>
#include <sys/signalfd.h>
+#include "wpa.h"
#ifdef __cplusplus
extern "C" {
@@ -74,6 +75,10 @@ void owfd_p2pd_ep_remove(int efd, int fd);
struct owfd_p2pd_interface;
+typedef void (*owfd_p2pd_interface_event_fn) (struct owfd_p2pd_interface *ifc,
+ struct owfd_wpa_event *ev,
+ void *data);
+
int owfd_p2pd_interface_new(struct owfd_p2pd_interface **out,
struct owfd_p2pd_config *conf, int efd);
void owfd_p2pd_interface_free(struct owfd_p2pd_interface *iface);
@@ -82,6 +87,13 @@ int owfd_p2pd_interface_dispatch(struct owfd_p2pd_interface *iface,
int owfd_p2pd_interface_dispatch_chld(struct owfd_p2pd_interface *iface,
struct signalfd_siginfo *info);
+int owfd_p2pd_interface_register_event_fn(struct owfd_p2pd_interface *iface,
+ owfd_p2pd_interface_event_fn event_fn,
+ void *data);
+void owfd_p2pd_interface_unregister_event_fn(struct owfd_p2pd_interface *iface,
+ owfd_p2pd_interface_event_fn event_fn,
+ void *data);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/p2pd_interface.c b/src/p2pd_interface.c
index 2bdaa65..c1f1db1 100644
--- a/src/p2pd_interface.c
+++ b/src/p2pd_interface.c
@@ -38,14 +38,23 @@
#include <unistd.h>
#include "p2pd.h"
#include "shared.h"
+#include "shl_dlist.h"
#include "shl_log.h"
#include "wpa.h"
+struct event_user {
+ struct shl_dlist list;
+ owfd_p2pd_interface_event_fn event_fn;
+ void *data;
+};
+
struct owfd_p2pd_interface {
struct owfd_wpa_ctrl *wpa;
struct owfd_p2pd_config *config;
int wpa_fd;
pid_t pid;
+
+ struct shl_dlist event_users;
};
static int wpa_setup(struct owfd_p2pd_interface *iface);
@@ -360,6 +369,7 @@ int owfd_p2pd_interface_new(struct owfd_p2pd_interface **out,
if (!iface)
return log_ENOMEM();
iface->config = conf;
+ shl_dlist_init(&iface->event_users);
r = owfd_wpa_ctrl_new(&iface->wpa);
if (r < 0) {
@@ -367,6 +377,7 @@ int owfd_p2pd_interface_new(struct owfd_p2pd_interface **out,
log_vERRNO();
goto err_iface;
}
+ owfd_wpa_ctrl_set_data(iface->wpa, iface);
r = fork_wpa(iface);
if (r < 0)
@@ -391,9 +402,18 @@ err_iface:
void owfd_p2pd_interface_free(struct owfd_p2pd_interface *iface)
{
+ struct event_user *e;
+
if (!iface)
return;
+ while (!shl_dlist_empty(&iface->event_users)) {
+ e = shl_dlist_entry(shl_dlist_first(&iface->event_users),
+ struct event_user, list);
+ shl_dlist_unlink(&e->list);
+ free(e);
+ }
+
kill_wpa(iface);
owfd_wpa_ctrl_close(iface->wpa);
owfd_wpa_ctrl_unref(iface->wpa);
@@ -429,6 +449,40 @@ int owfd_p2pd_interface_dispatch_chld(struct owfd_p2pd_interface *iface,
return OWFD_P2PD_EP_QUIT;
}
+int owfd_p2pd_interface_register_event_fn(struct owfd_p2pd_interface *iface,
+ owfd_p2pd_interface_event_fn event_fn,
+ void *data)
+{
+ struct event_user *e;
+
+ e = calloc(1, sizeof(*e));
+ if (!e)
+ return -ENOMEM;
+
+ e->event_fn = event_fn;
+ e->data = data;
+
+ shl_dlist_link(&iface->event_users, &e->list);
+ return 0;
+}
+
+void owfd_p2pd_interface_unregister_event_fn(struct owfd_p2pd_interface *iface,
+ owfd_p2pd_interface_event_fn event_fn,
+ void *data)
+{
+ struct shl_dlist *i;
+ struct event_user *e;
+
+ shl_dlist_for_each(i, &iface->event_users) {
+ e = shl_dlist_entry(i, struct event_user, list);
+ if (e->event_fn == event_fn && e->data == data) {
+ shl_dlist_unlink(&e->list);
+ free(e);
+ return;
+ }
+ }
+}
+
static int wpa_request_ok(struct owfd_p2pd_interface *iface, const char *req)
{
return owfd_wpa_ctrl_request_ok(iface->wpa, req, strlen(req), -1);
@@ -478,6 +532,9 @@ err_notsupp:
static void wpa_event(struct owfd_wpa_ctrl *wpa, void *buf,
size_t len, void *data)
{
+ struct owfd_p2pd_interface *iface = data;
+ struct shl_dlist *i, *t;
+ struct event_user *e;
struct owfd_wpa_event ev;
int r;
@@ -492,6 +549,12 @@ static void wpa_event(struct owfd_wpa_ctrl *wpa, void *buf,
} else {
log_debug("wpa-event (%d:%s): %s",
ev.type, owfd_wpa_event_name(ev.type), ev.raw);
+
+ shl_dlist_for_each_safe(i, t, &iface->event_users) {
+ e = shl_dlist_entry(i, struct event_user, list);
+ if (e->event_fn)
+ e->event_fn(iface, &ev, e->data);
+ }
}
owfd_wpa_event_reset(&ev);