diff options
-rw-r--r-- | tools/nfctool/main.c | 40 | ||||
-rw-r--r-- | tools/nfctool/netlink.c | 27 | ||||
-rw-r--r-- | tools/nfctool/netlink.h | 6 |
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); |