diff options
author | Raquel Medina <raquel.medina@konsulko.com> | 2018-11-25 02:17:48 +0200 |
---|---|---|
committer | Raquel Medina <raquel.medina@konsulko.com> | 2018-11-29 12:21:54 +0200 |
commit | 43ca26febeba4605e71ef99ce804b0dfa72074c8 (patch) | |
tree | bff3ca74fb6724434d27fc854672ce1c6ac89c5f | |
parent | a78b46e4824e5eba4103df52b997bfb871ce096e (diff) |
binding: nfc: Process content data from tag (adapter in tag reader mode)flounder_6.0.3flounder/6.0.36.0.3
Bug-AGL: SPEC-1975
- Register callback for tag found
- Update callback for record found
- Fix memory leak
Change-Id: I870648f3c5771aa1b54b710ef6b75786a1c67f65
Signed-off-by: Raquel Medina <raquel.medina@konsulko.com>
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | binding/afm-nfc-binding.c | 172 |
2 files changed, 130 insertions, 44 deletions
@@ -18,4 +18,4 @@ The NDEF data shall include a text record ('uid') to keep compatibility with the | Name | Description | JSON Response | |--------------------|:-------------------------------------|:-----------------------------------------------------------------------| | presence | event that reports NFC tag presence | *Response:* {"status": "detected", | -| | | "record": { "Type": "Text", "uid" : "042eb3628e4981"}, | +| | | "uid": "042eb3628e4981"}, | diff --git a/binding/afm-nfc-binding.c b/binding/afm-nfc-binding.c index 40caa5a..d605632 100644 --- a/binding/afm-nfc-binding.c +++ b/binding/afm-nfc-binding.c @@ -31,59 +31,133 @@ #include <neardal/neardal.h> #define AFB_BINDING_VERSION 3 #include <afb/afb-binding.h> - #include "afm-nfc-common.h" +#define STR(X) STR1(X) +#define STR1(X) #X + static afb_event_t presence_event; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -static void neard_cb_record_found(const char *tag_name, void *ptr) +static void __attribute__((unused)) dbg_dump_tag_records(neardal_tag *tag) +{ + char **recs = tag->records; + int i; + + if (!recs) { + AFB_API_DEBUG(afbBindingV3root, "tag empty!"); + return; + } + + for (i = 0; recs[i] != NULL; i++) + AFB_API_DEBUG(afbBindingV3root, "tag record[n]: %s", recs[i]); + + return; +} + +static void __attribute__((unused)) dbg_dump_record_content(neardal_record record) { +#define DBG_RECORD(__x) if (record.__x) \ + AFB_API_DEBUG(afbBindingV3root, "record %s=%s", STR(__x), (record.__x)) + + DBG_RECORD(authentication); + DBG_RECORD(representation); + DBG_RECORD(passphrase); + DBG_RECORD(encryption); + DBG_RECORD(encoding); + DBG_RECORD(language); + DBG_RECORD(action); + DBG_RECORD(mime); + DBG_RECORD(type); + DBG_RECORD(ssid); + DBG_RECORD(uri); +} + +static void record_found(const char *tag_name, void *ptr) +{ + json_object *jresp, *jdict, *jtemp; nfc_binding_data *data = ptr; neardal_record *record; + GVariant *value, *v = NULL; + GVariantIter iter; + char *s = NULL; + int ret; - int ret = neardal_get_record_properties(tag_name, &record); - if (ret == NEARDAL_SUCCESS) { - GVariantIter iter; - char *s = NULL; - GVariant *v, *value = (neardal_record_to_g_variant(record)); - json_object *jresp = json_object_new_object(); - json_object *jdict = json_object_new_object(); + ret = neardal_get_record_properties(tag_name, &record); + if (ret != NEARDAL_SUCCESS) { + AFB_API_ERROR(afbBindingV3root, + "read record properties for %s tag, err:0x%x (%s)", + tag_name, ret, neardal_error_get_text(ret)); + return; + } - g_variant_iter_init(&iter, value); - json_object_object_add(jresp, "status", - json_object_new_string("detected")); + value = neardal_record_to_g_variant(record); + jresp = json_object_new_object(); + jdict = json_object_new_object(); - while (g_variant_iter_loop(&iter, "{sv}", &s, &v)) { - gchar *str; + g_variant_iter_init(&iter, value); + json_object_object_add(jresp, + "status", json_object_new_string("detected")); - if (g_strcmp0("Name", s) == 0) - continue; + while (g_variant_iter_loop(&iter, "{sv}", &s, &v)) { + gchar *str = g_variant_print(v, 0); - str = g_variant_print(v, 0); - str[strlen(str) - 1] = '\0'; - json_object_object_add(jdict, s, - json_object_new_string(str + 1)); - g_free(str); - } + str[strlen(str) - 1] = '\0'; + AFB_API_DEBUG(afbBindingV3root, + "%s tag, record %s= %s", tag_name, s, str); - json_object_object_add(jresp, "record", jdict); + json_object_object_add(jdict, s, + json_object_new_string(str + 1)); + g_free(str); + } + + neardal_free_record(record); - neardal_free_record(record); + /* + * get record dictionary and look for 'Representation' field which should + * contain the uid value the identity agent needs. + * + */ + if (json_object_object_get_ex(jdict, "Representation", &jtemp)) { + const char *uid = json_object_get_string(jtemp); pthread_mutex_lock(&mutex); data->jresp = jresp; - json_object_get(jresp); + json_object_object_add(jresp, "uid", json_object_new_string(uid)); pthread_mutex_unlock(&mutex); afb_event_push(presence_event, jresp); - } + AFB_API_DEBUG(afbBindingV3root, + "sent presence event, record content %s, tag %s", + uid, tag_name); + } + + return; } -static void neard_cb_tag_removed(const char *tag_name, void *ptr) +static void tag_found(const char *tag_name, void *ptr) +{ + neardal_tag *tag; + int ret; + + ret = neardal_get_tag_properties(tag_name, &tag); + if (ret != NEARDAL_SUCCESS) { + AFB_API_ERROR(afbBindingV3root, + "read tag %s properties, err:0x%x (%s)", + tag_name, ret, neardal_error_get_text(ret)); + return; + } + + dbg_dump_tag_records(tag); + neardal_free_tag(tag); + + return; +} + +static void tag_removed(const char *tag_name, void *ptr) { nfc_binding_data *data = ptr; - json_object *jresp = json_object_new_object(); + json_object *jresp; pthread_mutex_lock(&mutex); if (data->jresp) { @@ -92,11 +166,12 @@ static void neard_cb_tag_removed(const char *tag_name, void *ptr) } pthread_mutex_unlock(&mutex); + jresp = json_object_new_object(); json_object_object_add(jresp, "status", json_object_new_string("removed")); - afb_event_push(presence_event, jresp); + AFB_API_DEBUG(afbBindingV3root, "%s tag removed, quit loop", tag_name); g_main_loop_quit(data->loop); } @@ -107,21 +182,22 @@ static void *poll_adapter(void *ptr) data->loop = g_main_loop_new(NULL, FALSE); - neardal_set_cb_tag_lost(neard_cb_tag_removed, ptr); - neardal_set_cb_record_found(neard_cb_record_found, ptr); + neardal_set_cb_tag_found(tag_found, ptr); + neardal_set_cb_tag_lost(tag_removed, ptr); + neardal_set_cb_record_found(record_found, ptr); ret = neardal_set_adapter_property(data->adapter, NEARD_ADP_PROP_POWERED, GINT_TO_POINTER(1)); if (ret != NEARDAL_SUCCESS) { AFB_API_DEBUG(afbBindingV3root, - "failed to power %s adapter on: ret=0x%x (%s)", - data->adapter, ret, neardal_error_get_text(ret)); - g_free(data->adapter); - return NULL; + "failed to power %s adapter on: ret=0x%x (%s)", + data->adapter, ret, neardal_error_get_text(ret)); + + goto out; } - while (1) { + for (;;) { ret = neardal_start_poll(data->adapter); if ((ret != NEARDAL_SUCCESS) && @@ -131,7 +207,11 @@ static void *poll_adapter(void *ptr) g_main_loop_run(data->loop); } + AFB_API_DEBUG(afbBindingV3root, "exiting polling loop"); + +out: g_free(data->adapter); + free(data); return NULL; } @@ -146,7 +226,6 @@ static int get_adapter(nfc_binding_data *data, unsigned int id) AFB_API_DEBUG(afbBindingV3root, "failed to find adapters ret=0x%x (%s)", ret, neardal_error_get_text(ret)); - return -EIO; } @@ -154,12 +233,14 @@ static int get_adapter(nfc_binding_data *data, unsigned int id) AFB_API_DEBUG(afbBindingV3root, "adapter out of range (%d - %d)", id, num_adapters); - return -EINVAL; + ret = -EINVAL; + goto out; } data->adapter = g_strdup(adapters[id]); - neardal_free_array(&adapters); +out: + neardal_free_array(&adapters); return ret; } @@ -174,20 +255,26 @@ static int init(afb_api_t api) presence_event = afb_api_make_event(api, "presence"); if (!afb_event_is_valid(presence_event)) { AFB_API_ERROR(api, "Failed to create event"); + free(data); return -EINVAL; } /* get the first adapter */ ret = get_adapter(data, 0); - if (ret != NEARDAL_SUCCESS) - return 0; + if (ret != NEARDAL_SUCCESS) { + free(data); + return 0; /* ignore error if no adapter */ + } AFB_API_DEBUG(api, " %s adapter found", data->adapter); afb_api_set_userdata(api, data); ret = pthread_create(&thread_id, NULL, poll_adapter, data); - if (ret) + if (ret) { AFB_API_ERROR(api, "polling pthread creation failed"); + g_free(data->adapter); + free(data); + } return 0; } @@ -235,4 +322,3 @@ const afb_binding_t afbBindingExport = { .verbs = binding_verbs, .init = init }; - |