summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/nfctool/main.c40
-rw-r--r--tools/nfctool/netlink.c27
-rw-r--r--tools/nfctool/netlink.h6
3 files changed, 45 insertions, 28 deletions
diff --git a/tools/nfctool/main.c b/tools/nfctool/main.c
index 1b9a266..d0fe128 100644
--- a/tools/nfctool/main.c
+++ b/tools/nfctool/main.c
@@ -39,6 +39,10 @@
static GMainLoop *main_loop = NULL;
+static int nfctool_poll_cb(guint8 cmd, guint32 idx, gpointer data);
+
+static void nfctool_quit(gboolean force);
+
static gchar *nfctool_poll_mode_str(int mode)
{
if (mode == POLLING_MODE_TARGET)
@@ -64,6 +68,9 @@ static int nfctool_start_poll(void)
return -ENODEV;
}
+ nl_add_event_handler(NFC_EVENT_TARGETS_FOUND, nfctool_poll_cb);
+ nl_add_event_handler(NFC_EVENT_TM_ACTIVATED, nfctool_poll_cb);
+
err = nl_start_poll(adapter, opts.poll_mode);
if (err == 0) {
@@ -106,16 +113,6 @@ exit:
return err;
}
-static int nfctool_tm_activated(void)
-{
- printf("Target mode activated\n");
-
- if (!opts.sniff)
- g_main_loop_quit(main_loop);
-
- return 0;
-}
-
static void nfctool_send_dep_link_up(guint32 target_idx, guint32 adapter_idx)
{
nl_send_dep_link_up(adapter_idx, target_idx);
@@ -154,27 +151,26 @@ static int nfctool_targets_found(guint32 adapter_idx)
}
exit:
- if (!opts.sniff)
- g_main_loop_quit(main_loop);
-
return err;
}
-static int nfc_event_cb(guint8 cmd, guint32 idx)
+static int nfctool_poll_cb(guint8 cmd, guint32 idx, gpointer data)
{
int err = 0;
+ DBG("cmd: %d, idx: %d", cmd, idx);
+
switch (cmd) {
case NFC_EVENT_TARGETS_FOUND:
- DBG("Targets found");
err = nfctool_targets_found(idx);
break;
case NFC_EVENT_TM_ACTIVATED:
- DBG("Target mode activated");
- err = nfctool_tm_activated();
+ printf("Target mode activated\n");
break;
}
+ nfctool_quit(FALSE);
+
return err;
}
@@ -189,7 +185,7 @@ static void sig_term(int sig)
DBG("Terminating");
- g_main_loop_quit(main_loop);
+ nfctool_quit(TRUE);
}
struct nfctool_options opts = {
@@ -433,6 +429,12 @@ static void nfctool_main_loop_clean(void)
g_main_loop_unref(main_loop);
}
+static void nfctool_quit(gboolean force)
+{
+ if (force || !opts.sniff)
+ g_main_loop_quit(main_loop);
+}
+
int main(int argc, char **argv)
{
int err;
@@ -444,7 +446,7 @@ int main(int argc, char **argv)
adapter_init();
if (opts.need_netlink) {
- err = nl_init(nfc_event_cb);
+ err = nl_init();
if (err)
goto exit_err;
diff --git a/tools/nfctool/netlink.c b/tools/nfctool/netlink.c
index edaefef..f27deeb 100644
--- a/tools/nfctool/netlink.c
+++ b/tools/nfctool/netlink.c
@@ -77,7 +77,7 @@ static struct nlnfc_state *nfc_state = NULL;
static GIOChannel *nl_gio_channel = NULL;
-static nfc_event_cb_t nfc_event_cb = NULL;
+static GHashTable *handlers = NULL;
static int nl_error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
void *arg)
@@ -561,9 +561,9 @@ static int nl_nfc_event_cb(struct nl_msg *n, void *arg)
guint32 idx = INVALID_ADAPTER_IDX;
struct nlattr *attr[NFC_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(n));
+ nfc_event_cb_t cb = NULL;
- if (nfc_event_cb == NULL)
- return NL_SKIP;
+ DBG("Received cmd %d", gnlh->cmd);
nla_parse(attr, NFC_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
@@ -571,7 +571,11 @@ static int nl_nfc_event_cb(struct nl_msg *n, void *arg)
if (attr[NFC_ATTR_DEVICE_INDEX] != NULL)
idx = nla_get_u32(attr[NFC_ATTR_DEVICE_INDEX]);
- nfc_event_cb(gnlh->cmd, idx);
+ if (handlers != NULL)
+ cb = g_hash_table_lookup(handlers, GINT_TO_POINTER(gnlh->cmd));
+
+ if (cb != NULL)
+ cb(gnlh->cmd, idx, NULL);
return NL_SKIP;
}
@@ -599,6 +603,12 @@ static gboolean nl_gio_handler(GIOChannel *channel,
return TRUE;
}
+void nl_add_event_handler(guint8 cmd, nfc_event_cb_t cb)
+{
+ if (handlers != NULL)
+ g_hash_table_replace(handlers, GINT_TO_POINTER(cmd), cb);
+}
+
void nl_cleanup(void)
{
if (nl_gio_channel) {
@@ -617,9 +627,12 @@ void nl_cleanup(void)
g_free(nfc_state);
nfc_state = NULL;
}
+
+ if (handlers != NULL)
+ g_hash_table_remove_all(handlers);
}
-int nl_init(nfc_event_cb_t cb)
+int nl_init(void)
{
int err;
int fd;
@@ -676,6 +689,8 @@ int nl_init(nfc_event_cb_t cb)
goto exit_err;
}
+ handlers = g_hash_table_new(g_direct_hash, g_direct_equal);
+
fd = nl_socket_get_fd(nfc_state->event_sock);
nl_gio_channel = g_io_channel_unix_new(fd);
g_io_channel_set_close_on_unref(nl_gio_channel, TRUE);
@@ -687,8 +702,6 @@ int nl_init(nfc_event_cb_t cb)
G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
nl_gio_handler, nfc_state);
- nfc_event_cb = cb;
-
return 0;
exit_err:
diff --git a/tools/nfctool/netlink.h b/tools/nfctool/netlink.h
index 88b2889..c8dc66a 100644
--- a/tools/nfctool/netlink.h
+++ b/tools/nfctool/netlink.h
@@ -21,14 +21,16 @@
#ifndef __NETLINK_H
#define __NETLINK_H
-typedef int (*nfc_event_cb_t)(guint8 cmd, guint32 adapter_idx);
+typedef int (*nfc_event_cb_t)(guint8 cmd, guint32 adapter_idx, gpointer data);
struct nfc_adapter;
-int nl_init(nfc_event_cb_t cb);
+int nl_init(void);
void nl_cleanup(void);
+void nl_add_event_handler(guint8 cmd, nfc_event_cb_t cb);
+
int nl_get_devices(void);
int nl_get_targets(struct nfc_adapter *adapter);