aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--binding/afm-nfc-binding.c172
2 files changed, 130 insertions, 44 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 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
};
-