aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaquel Medina <raquel.medina@konsulko.com>2018-11-25 02:17:48 +0200
committerraquel medina <raquel.medina@konsulko.com>2018-11-28 17:43:04 +0000
commitb7cae49a6d1b4c5dba12647e2b30e635b8993a92 (patch)
tree4d3edda8254e7de472356c1434c5304f279a5d60
parent557e5f053411a3319c4f3efb5c56ad09f0de553b (diff)
binding: nfc: Process content data from tag (adapter in tag reader mode)
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.md2
-rw-r--r--binding/afm-nfc-binding.c292
2 files changed, 190 insertions, 104 deletions
diff --git a/README.md b/README.md
index a1d9471..a9eec9b 100644
--- a/README.md
+++ b/README.md
@@ -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 6fc26d9..1037227 100644
--- a/binding/afm-nfc-binding.c
+++ b/binding/afm-nfc-binding.c
@@ -31,109 +31,190 @@
#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 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static afb_event_t presence_event;
-static void neard_cb_record_found(const char *tag_name, void *ptr)
+static void __attribute__((unused)) dbg_dump_tag_records(neardal_tag *tag)
{
- nfc_binding_data *data = ptr;
- neardal_record *record;
+ char **recs = tag->records;
+ int i;
- 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();
+ if (!recs) {
+ AFB_API_DEBUG(afbBindingV3root, "tag empty!");
+ return;
+ }
- g_variant_iter_init(&iter, value);
- json_object_object_add(jresp, "status",
- json_object_new_string("detected"));
+ for (i = 0; recs[i] != NULL; i++)
+ AFB_API_DEBUG(afbBindingV3root, "tag record[n]: %s", recs[i]);
- while (g_variant_iter_loop(&iter, "{sv}", &s, &v)) {
- gchar *str;
+ return;
+}
- if (g_strcmp0("Name", s) == 0)
- continue;
- 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);
- }
+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);
+}
- json_object_object_add(jresp, "record", jdict);
+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;
+
+ 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;
+ }
- neardal_free_record(record);
+ value = neardal_record_to_g_variant(record);
+ jresp = json_object_new_object();
+ jdict = json_object_new_object();
- pthread_mutex_lock(&mutex);
- data->jresp = jresp;
- json_object_get(jresp);
- pthread_mutex_unlock(&mutex);
+ g_variant_iter_init(&iter, value);
+ json_object_object_add(jresp,
+ "status", json_object_new_string("detected"));
- afb_event_push(presence_event, jresp);
- }
+ while (g_variant_iter_loop(&iter, "{sv}", &s, &v)) {
+ gchar *str = g_variant_print(v, 0);
+
+ str[strlen(str) - 1] = '\0';
+ AFB_API_DEBUG(afbBindingV3root,
+ "%s tag, record %s= %s", tag_name, s, str);
+
+ json_object_object_add(jdict, s,
+ json_object_new_string(str + 1));
+ g_free(str);
+ }
+
+ 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_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)
{
- nfc_binding_data *data = ptr;
- json_object *jresp = json_object_new_object();
+ neardal_tag *tag;
+ int ret;
- pthread_mutex_lock(&mutex);
- if (data->jresp) {
- json_object_put(data->jresp);
- data->jresp = NULL;
- }
- pthread_mutex_unlock(&mutex);
-
- json_object_object_add(jresp, "status",
- json_object_new_string("removed"));
+ 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;
+
+ pthread_mutex_lock(&mutex);
+ if (data->jresp) {
+ json_object_put(data->jresp);
+ data->jresp = NULL;
+ }
+ pthread_mutex_unlock(&mutex);
- afb_event_push(presence_event, jresp);
+ jresp = json_object_new_object();
+ json_object_object_add(jresp, "status",
+ json_object_new_string("removed"));
+ afb_event_push(presence_event, jresp);
- g_main_loop_quit(data->loop);
+ AFB_API_DEBUG(afbBindingV3root, "%s tag removed, quit loop", tag_name);
+ g_main_loop_quit(data->loop);
}
static void *poll_adapter(void *ptr)
{
- nfc_binding_data *data = ptr;
- int ret;
-
- 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);
-
- 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;
- }
+ nfc_binding_data *data = ptr;
+ int ret;
- while (1) {
- ret = neardal_start_poll(data->adapter);
+ data->loop = g_main_loop_new(NULL, FALSE);
- if ((ret != NEARDAL_SUCCESS) &&
- (ret != NEARDAL_ERROR_POLLING_ALREADY_ACTIVE))
- break;
+ neardal_set_cb_tag_found(tag_found, ptr);
+ neardal_set_cb_tag_lost(tag_removed, ptr);
+ neardal_set_cb_record_found(record_found, ptr);
- g_main_loop_run(data->loop);
- }
+ 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));
+
+ goto out;
+ }
+
+ for (;;) {
+ ret = neardal_start_poll(data->adapter);
+
+ if ((ret != NEARDAL_SUCCESS) &&
+ (ret != NEARDAL_ERROR_POLLING_ALREADY_ACTIVE))
+ break;
+
+ g_main_loop_run(data->loop);
+ }
- g_free(data->adapter);
+ AFB_API_DEBUG(afbBindingV3root, "exiting polling loop");
- return NULL;
+out:
+ g_free(data->adapter);
+ free(data);
+
+ return NULL;
}
static int get_adapter(nfc_binding_data *data, unsigned int id)
@@ -146,52 +227,59 @@ 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;
}
if (id > num_adapters - 1) {
- AFB_API_DEBUG(afbBindingV3root,
- "adapter out of range (%d - %d)",
+ 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;
}
static int init(afb_api_t api)
{
- nfc_binding_data *data;
- pthread_t thread_id;
- int ret;
-
- data = malloc(sizeof(nfc_binding_data));
- if (data == NULL)
- return -ENOMEM;
-
- presence_event = afb_api_make_event(api, "presence");
- if (!afb_event_is_valid(presence_event)) {
- AFB_API_ERROR(api, "Failed to create event");
- return -EINVAL;
- }
+ nfc_binding_data *data;
+ pthread_t thread_id;
+ int ret;
+
+ data = malloc(sizeof(nfc_binding_data));
+ if (!data)
+ return -ENOMEM;
+
+ 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;
+ ret = get_adapter(data, 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;
+ return 0;
}
static void subscribe(afb_req_t request)
@@ -202,15 +290,14 @@ static void subscribe(afb_req_t request)
return;
}
-
+
afb_req_reply(request, NULL, NULL, NULL);
}
static void unsubscribe(afb_req_t request)
{
if (afb_req_unsubscribe(request, presence_event) < 0) {
- AFB_REQ_ERROR(request,
- "unsubscribe to presence_event failed");
+ AFB_REQ_ERROR(request, "unsubscribe to presence_event failed");
afb_req_reply(request, NULL, "failed", "Invalid event");
return;
@@ -219,10 +306,10 @@ static void unsubscribe(afb_req_t request)
afb_req_reply(request, NULL, NULL, NULL);
}
-const afb_verb_t binding_verbs[] = {
- { .verb = "subscribe", .callback = subscribe,
+static const afb_verb_t binding_verbs[] = {
+ { .verb = "subscribe", .callback = subscribe,
.info = "Subscribe to NFC events" },
- { .verb = "unsubscribe", .callback = unsubscribe,
+ { .verb = "unsubscribe", .callback = unsubscribe,
.info = "Unsubscribe to NFC events" },
{ .verb = NULL }
};
@@ -240,4 +327,3 @@ const afb_binding_t afbBindingExport = {
.onevent = NULL,
.noconcurrency = 0
};
-