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)
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) {
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);
}
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;
}
DBG("Terminating");
- g_main_loop_quit(main_loop);
+ nfctool_quit(TRUE);
}
struct nfctool_options opts = {
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;
adapter_init();
if (opts.need_netlink) {
- err = nl_init(nfc_event_cb);
+ err = nl_init();
if (err)
goto exit_err;
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)
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);
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;
}
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) {
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;
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);
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:
#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);