aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--binding/afm-nfc-binding.c220
1 files changed, 187 insertions, 33 deletions
diff --git a/binding/afm-nfc-binding.c b/binding/afm-nfc-binding.c
index 5331d6c..7d0f6dc 100644
--- a/binding/afm-nfc-binding.c
+++ b/binding/afm-nfc-binding.c
@@ -39,26 +39,28 @@
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static afb_event_t presence_event;
-static void __attribute__((unused)) dbg_dump_tag_records(neardal_tag *tag)
+static void __attribute__((unused)) dbg_dump_adapter_info(neardal_adapter *adp)
{
- char **recs = tag->records;
- int i;
+#define DBG_ADP(__x) if (adp->__x) \
+ AFB_API_DEBUG(afbBindingV3root, "adapter %s=%s\n", STR(__x), (adp->__x))
- if (!recs) {
- AFB_API_DEBUG(afbBindingV3root, "tag empty!");
- return;
- }
+ DBG_ADP(name);
+ DBG_ADP(mode);
+}
- for (i = 0; recs[i] != NULL; i++)
- AFB_API_DEBUG(afbBindingV3root, "tag record[n]: %s", recs[i]);
+static void __attribute__((unused)) dbg_dump_tag_info(neardal_tag *tag)
+{
+#define DBG_TAG(__x) if (tag->__x) \
+ AFB_API_DEBUG(afbBindingV3root, "tag %s=%s\n", STR(__x), (tag->__x))
- return;
+ DBG_TAG(name);
+ DBG_TAG(type);
}
-static void __attribute__((unused)) dbg_dump_record_content(neardal_record record)
+static void __attribute__((unused)) dbg_dump_record_content(neardal_record *rcd)
{
-#define DBG_RECORD(__x) if (record.__x) \
- AFB_API_DEBUG(afbBindingV3root, "record %s=%s", STR(__x), (record.__x))
+#define DBG_RECORD(__x) if (rcd->__x) \
+ AFB_API_DEBUG(afbBindingV3root, "record %s=%s", STR(__x), (rcd->__x))
DBG_RECORD(authentication);
DBG_RECORD(representation);
@@ -73,6 +75,95 @@ static void __attribute__((unused)) dbg_dump_record_content(neardal_record recor
DBG_RECORD(uri);
}
+static void adapter_added(const char *aname, void *ptr)
+{
+ nfc_binding_data *data = ptr;
+ neardal_adapter*adapter;
+ int ret;
+
+ if (!aname || !ptr)
+ return;
+
+ ret = neardal_get_adapter_properties(aname, &adapter);
+ if (ret != NEARDAL_SUCCESS) {
+ AFB_API_ERROR(afbBindingV3root,
+ "'%s', cant get properties!\n", aname);
+ return;
+ }
+ dbg_dump_adapter_info(adapter);
+
+ if (data->adapter) {
+ AFB_API_DEBUG(afbBindingV3root,
+ "ignoring new if: '%s', using '%s'\n",
+ aname, data->adapter);
+ return;
+ }
+
+ data->adapter = g_strdup(aname);
+}
+
+static void adapter_removed(const char *aname, void *ptr)
+{
+ nfc_binding_data *data = ptr;
+ neardal_adapter*adapter;
+ int ret;
+
+ if (!data || !data->adapter)
+ return;
+
+ if (!strcmp(data->adapter, aname)) {
+ g_free(data->adapter);
+ data->adapter = NULL;
+ }
+
+ AFB_API_DEBUG(afbBindingV3root, "'%s removed'\n", aname);
+
+ g_main_loop_quit(data->loop);
+}
+
+static void adapter_prop_changed(char *aname, char *prop,
+ void *value, void *cookie)
+{
+ nfc_binding_data *data;
+ unsigned int val;
+ int ret = NEARDAL_SUCCESS;
+
+ if (!value || !prop || !aname || !cookie)
+ return;
+
+ data = cookie;
+ val = GPOINTER_TO_UINT(value);
+ AFB_API_DEBUG(afbBindingV3root, "'%s' -> %s=0x%X\n", aname, prop, val);
+
+ if (!strcmp(prop, "Polling") && !val)
+ ret = neardal_start_poll(data->adapter);
+
+ if ((ret != NEARDAL_SUCCESS) &&
+ (ret != NEARDAL_ERROR_POLLING_ALREADY_ACTIVE)) {
+ AFB_API_ERROR(afbBindingV3root,
+ "failed to start polling %s : ret=0x%x (%s)\n",
+ data->adapter, ret, neardal_error_get_text(ret));
+ goto out;
+ }
+
+ if (!strcmp(prop, "Powered") && !val)
+ ret = neardal_set_adapter_property(data->adapter,
+ NEARD_ADP_PROP_POWERED,
+ GINT_TO_POINTER(1));
+ if (ret != NEARDAL_SUCCESS) {
+ AFB_API_ERROR(afbBindingV3root,
+ "failed to power %s : ret=0x%x (%s)\n",
+ data->adapter, ret, neardal_error_get_text(ret));
+ goto out;
+ }
+
+ if (!strcmp(prop, "Mode"))
+ AFB_API_DEBUG(afbBindingV3root, "%s, %s, %s \n", aname, prop,
+ (char*)value);
+out:
+ return;
+}
+
static void record_found(const char *tag_name, void *ptr)
{
json_object *jresp, *jdict, *jtemp;
@@ -83,6 +174,9 @@ static void record_found(const char *tag_name, void *ptr)
char *s = NULL;
int ret;
+ if (!tag_name || !ptr)
+ return;
+
ret = neardal_get_record_properties(tag_name, &record);
if (ret != NEARDAL_SUCCESS) {
AFB_API_ERROR(afbBindingV3root,
@@ -111,6 +205,7 @@ static void record_found(const char *tag_name, void *ptr)
g_free(str);
}
+ dbg_dump_record_content(record);
neardal_free_record(record);
/*
@@ -140,6 +235,9 @@ static void tag_found(const char *tag_name, void *ptr)
neardal_tag *tag;
int ret;
+ if (!tag_name)
+ return;
+
ret = neardal_get_tag_properties(tag_name, &tag);
if (ret != NEARDAL_SUCCESS) {
AFB_API_ERROR(afbBindingV3root,
@@ -148,17 +246,20 @@ static void tag_found(const char *tag_name, void *ptr)
return;
}
- dbg_dump_tag_records(tag);
+ dbg_dump_tag_info(tag);
neardal_free_tag(tag);
return;
}
-static void tag_removed(const char *tag_name, void *ptr)
+static void tag_lost(const char *tag_name, void *ptr)
{
nfc_binding_data *data = ptr;
json_object *jresp;
+ if (!tag_name || !ptr)
+ return;
+
pthread_mutex_lock(&mutex);
if (data->jresp) {
json_object_put(data->jresp);
@@ -175,52 +276,103 @@ static void tag_removed(const char *tag_name, void *ptr)
g_main_loop_quit(data->loop);
}
+static void install_adapter_callbacks(void *usrptr)
+{
+ neardal_set_cb_adapter_added(adapter_added, usrptr);
+ neardal_set_cb_adapter_removed(adapter_removed, usrptr);
+ neardal_set_cb_adapter_property_changed(adapter_prop_changed, usrptr);
+ AFB_API_DEBUG(afbBindingV3root, "NFC adapter callbacks registered\n");
+}
+
+static void install_tag_callbacks(void *usrptr)
+{
+ neardal_set_cb_tag_found(tag_found, usrptr);
+ neardal_set_cb_tag_lost(tag_lost, usrptr);
+ neardal_set_cb_record_found(record_found, usrptr);
+ AFB_API_DEBUG(afbBindingV3root, "NFC tag callbacks registered\n");
+}
+
+static void remove_adapter_callbacks(void *usrptr)
+{
+ neardal_set_cb_adapter_added(NULL, usrptr);
+ neardal_set_cb_adapter_removed(NULL, usrptr);
+ neardal_set_cb_adapter_property_changed(NULL, usrptr);
+ AFB_API_DEBUG(afbBindingV3root, "NFC adapter callbacks removed\n");
+}
+
+static void remove_tag_callbacks(void *usrptr)
+{
+ neardal_set_cb_tag_found(NULL, usrptr);
+ neardal_set_cb_tag_lost(NULL, usrptr);
+ neardal_set_cb_record_found(NULL, usrptr);
+ AFB_API_DEBUG(afbBindingV3root, "NFC tag callbacks removed\n");
+}
+
static void *poll_adapter(void *ptr)
{
+ neardal_adapter* nfcdev = NULL;
nfc_binding_data *data = ptr;
int ret;
- data->loop = g_main_loop_new(NULL, FALSE);
+ if (!data)
+ return NULL;
+
+ install_adapter_callbacks(data);
+
+ ret = neardal_get_adapter_properties(data->adapter, &nfcdev);
+ if (ret != NEARDAL_SUCCESS) {
+ AFB_API_ERROR(afbBindingV3root,
+ "configuring '%s', cant get properties!\n",
+ data->adapter);
+ goto out;
+ }
- neardal_set_cb_tag_found(tag_found, ptr);
- neardal_set_cb_tag_lost(tag_removed, ptr);
- neardal_set_cb_record_found(record_found, ptr);
+ if (nfcdev->powered)
+ goto ploop;
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)",
+ if (ret != NEARDAL_SUCCESS)
+ AFB_API_ERROR(afbBindingV3root,
+ "failed to power up %s adapter: ret=0x%x (%s)\n",
data->adapter, ret, neardal_error_get_text(ret));
- goto out;
- }
+ploop:
+ neardal_free_adapter(nfcdev);
+
+ data->loop = g_main_loop_new(NULL, FALSE);
for (;;) {
+ install_tag_callbacks(data);
+
ret = neardal_start_poll(data->adapter);
+ if ((ret == NEARDAL_SUCCESS) ||
+ (ret == NEARDAL_ERROR_POLLING_ALREADY_ACTIVE))
+ g_main_loop_run(data->loop);
- if ((ret != NEARDAL_SUCCESS) &&
- (ret != NEARDAL_ERROR_POLLING_ALREADY_ACTIVE))
+ remove_tag_callbacks(data);
+ if (data->adapter == NULL)
break;
-
- g_main_loop_run(data->loop);
}
AFB_API_DEBUG(afbBindingV3root, "exiting polling loop");
out:
g_free(data->adapter);
- free(data);
+ g_free(data);
return NULL;
}
-static int get_adapter(nfc_binding_data *data, unsigned int id)
+static int get_adapter(nfc_binding_data *const data, unsigned int id)
{
char **adapters = NULL;
int num_adapters, ret;
+ if (!data)
+ return -EINVAL;
+
ret = neardal_get_adapters(&adapters, &num_adapters);
if (ret != NEARDAL_SUCCESS) {
AFB_API_DEBUG(afbBindingV3root,
@@ -255,14 +407,16 @@ 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);
+ g_free(data);
return -EINVAL;
}
/* get the first adapter */
ret = get_adapter(data, 0);
if (ret != NEARDAL_SUCCESS) {
- free(data);
+ AFB_API_ERROR(api,
+ "Failed to get adapter. Please start neard.\n");
+ g_free(data);
return 0; /* ignore error if no adapter */
}
@@ -273,7 +427,7 @@ static int init(afb_api_t api)
if (ret) {
AFB_API_ERROR(api, "polling pthread creation failed");
g_free(data->adapter);
- free(data);
+ g_free(data);
}
return 0;