From 084463b264b1cead384874ef8d67dd530225f024 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 8 Jun 2011 16:09:13 +0200 Subject: [PATCH] tag: Add reader callback support --- include/tag.h | 5 ++++- plugins/nfctype2.c | 57 ++++++++++++++++++++++++++++++++++++++++-------------- src/adapter.c | 20 ++++++++++++++++--- src/near.h | 2 +- src/tag.c | 4 ++-- 5 files changed, 67 insertions(+), 21 deletions(-) diff --git a/include/tag.h b/include/tag.h index 3b09f52..0d9280b 100644 --- a/include/tag.h +++ b/include/tag.h @@ -37,10 +37,13 @@ #define NEAR_TAG_NFC_DEP 0x10 #define NEAR_TAG_NFC_UNKNOWN 0xff +typedef void (*near_tag_read_cb) (uint32_t adapter_idx, int status); + struct near_tag_driver { uint16_t type; - int (*read_tag)(uint32_t adapter_idx, uint32_t target_idx); + int (*read_tag)(uint32_t adapter_idx, uint32_t target_idx, + near_tag_read_cb cb); }; struct near_tag; diff --git a/plugins/nfctype2.c b/plugins/nfctype2.c index 3d541ed..214f2de 100644 --- a/plugins/nfctype2.c +++ b/plugins/nfctype2.c @@ -67,8 +67,10 @@ struct type2_cmd { } __attribute__((packed)); struct type2_tag { + uint32_t adapter_idx; uint16_t current_block; + near_tag_read_cb cb; struct near_tag *tag; }; @@ -120,7 +122,7 @@ static uint8_t *tlv_data(uint8_t *data) return data + 1 + l_length; } -static int data_parse(struct near_tag *tag, uint8_t *data, uint16_t length) +static int data_parse(struct type2_tag *tag, uint8_t *data, uint16_t length) { uint8_t *tlv = data, t; @@ -135,13 +137,17 @@ static int data_parse(struct near_tag *tag, uint8_t *data, uint16_t length) case TLV_NDEF: DBG("NDEF found %d bytes long", tlv_length(tlv)); - near_tag_add_ndef(tag, tlv_data(tlv), tlv_length(tlv)); + near_tag_add_ndef(tag->tag, tlv_data(tlv), + tlv_length(tlv)); break; case TLV_END: - return 0; + break; } + if (t == TLV_END) + break; + tlv = next_tlv(tlv); if (tlv - data >= length) @@ -150,6 +156,9 @@ static int data_parse(struct near_tag *tag, uint8_t *data, uint16_t length) DBG("Done"); + if (tag->cb) + tag->cb(tag->adapter_idx, 0); + return 0; } @@ -187,7 +196,7 @@ static int data_recv(uint8_t *resp, int length, void *data) DBG("Done reading"); - data_parse(tag->tag, nfc_data, data_length); + data_parse(tag, nfc_data, data_length); g_free(tag); @@ -226,9 +235,15 @@ static int data_read(struct type2_tag *tag) data_recv, tag); } +struct recv_cookie { + uint32_t adapter_idx; + uint32_t target_idx; + near_tag_read_cb cb; +}; + static int meta_recv(uint8_t *resp, int length, void *data) { - uint32_t *target_idx = data; + struct recv_cookie *cookie = data; struct near_tag *tag; struct type2_tag *t2_tag; uint8_t *cc; @@ -253,13 +268,20 @@ static int meta_recv(uint8_t *resp, int length, void *data) goto out; } - tag = near_target_get_tag(*target_idx, TAG_DATA_LENGTH(cc)); + tag = near_target_get_tag(cookie->target_idx, TAG_DATA_LENGTH(cc)); if (tag == NULL) { err = -ENOMEM; goto out; } t2_tag = g_try_malloc0(sizeof(struct type2_tag)); + if (t2_tag == NULL) { + err = -ENOMEM; + goto out; + } + + t2_tag->adapter_idx = cookie->adapter_idx; + t2_tag->cb = cookie->cb; t2_tag->tag = tag; near_tag_set_uid(tag, resp + NFC_HEADER_SIZE, 8); @@ -267,29 +289,36 @@ static int meta_recv(uint8_t *resp, int length, void *data) err = data_read(t2_tag); out: - g_free(data); + g_free(cookie); + + if (err < 0 && cookie->cb) + cookie->cb(cookie->adapter_idx, err); return err; } -static int nfctype2_read_meta(uint32_t adapter_idx, uint32_t target_idx) +static int nfctype2_read_meta(uint32_t adapter_idx, uint32_t target_idx, + near_tag_read_cb cb) { struct type2_cmd cmd; - uint32_t *idx; + struct recv_cookie *cookie; DBG(""); cmd.cmd = CMD_READ; cmd.block = META_BLOCK_START; - idx = g_try_malloc0(sizeof(uint32_t)); - *idx = target_idx; + cookie = g_try_malloc0(sizeof(struct recv_cookie)); + cookie->adapter_idx = adapter_idx; + cookie->target_idx = target_idx; + cookie->cb = cb; - return near_adapter_send(adapter_idx, (uint8_t *)&cmd, sizeof(cmd), meta_recv, idx); + return near_adapter_send(adapter_idx, (uint8_t *)&cmd, sizeof(cmd), + meta_recv, cookie); } static int nfctype2_read_tag(uint32_t adapter_idx, - uint32_t target_idx) + uint32_t target_idx, near_tag_read_cb cb) { int err; @@ -302,7 +331,7 @@ static int nfctype2_read_tag(uint32_t adapter_idx, return err; } - err = nfctype2_read_meta(adapter_idx, target_idx); + err = nfctype2_read_meta(adapter_idx, target_idx, cb); if (err < 0) near_adapter_disconnect(adapter_idx); diff --git a/src/adapter.c b/src/adapter.c index eade985..626bbe9 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -341,6 +341,22 @@ void __near_adapter_remove(struct near_adapter *adapter) g_hash_table_remove(adapter_hash, GINT_TO_POINTER(adapter->idx)); } +static void tag_read_cb(uint32_t adapter_idx, int status) +{ + struct near_adapter *adapter; + + DBG("%d", status); + + if (status < 0) + return; + + adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(adapter_idx)); + if (adapter == NULL) + return; + + target_changed(adapter); +} + int __near_adapter_add_target(uint32_t idx, struct near_target *target) { struct near_adapter *adapter; @@ -360,9 +376,7 @@ int __near_adapter_add_target(uint32_t idx, struct near_target *target) polling_changed(adapter); - target_changed(adapter); - - __near_tag_read(target); + __near_tag_read(target, tag_read_cb); return 0; } diff --git a/src/near.h b/src/near.h index 9b081fa..2edfd6b 100644 --- a/src/near.h +++ b/src/near.h @@ -107,7 +107,7 @@ void __near_target_cleanup(void); struct near_tag *__near_tag_new(uint32_t adapter_idx, uint32_t target_idx, size_t data_length); void __near_tag_free(struct near_tag *tag); -int __near_tag_read(struct near_target *target); +int __near_tag_read(struct near_target *target, near_tag_read_cb cb); int __near_netlink_get_adapters(void); int __near_netlink_start_poll(int idx, uint32_t protocols); diff --git a/src/tag.c b/src/tag.c index b3851a6..446435a 100644 --- a/src/tag.c +++ b/src/tag.c @@ -154,7 +154,7 @@ void near_tag_driver_unregister(struct near_tag_driver *driver) driver_list = g_list_remove(driver_list, driver); } -int __near_tag_read(struct near_target *target) +int __near_tag_read(struct near_target *target,near_tag_read_cb cb) { GList *list; uint16_t type; @@ -178,7 +178,7 @@ int __near_tag_read(struct near_target *target) target_idx = __near_target_get_idx(target); adapter_idx = __near_target_get_adapter_idx(target); - return driver->read_tag(adapter_idx, target_idx); + return driver->read_tag(adapter_idx, target_idx, cb); } } -- 2.7.4