aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaquel Medina <raquel.medina@konsulko.com>2019-01-05 00:51:05 +0200
committerRaquel Medina <raquel.medina@konsulko.com>2019-01-07 14:34:36 +0200
commitf352283da17c024313e1de200698dda1476c612e (patch)
tree50115b7c3dc75705d5ddc87c61134332c84ef046
parentaab5e5d8ff58b2ec6503615efb9ea35e9f0d93f2 (diff)
binding: nfc: increase safety checks around neardal api calls.halibut_7.90.0halibut/7.90.0guppy_6.99.4guppy/6.99.47.90.06.99.4
Bug-AGL: SPEC-2062 When the NFC adapter is powered up and agl-service-nfc sends a request to power it, or when the NFC adapter is actively polling and agl-service-nfc sends a request to start polling, the requests are being rejected and an error message issued. The changes in this commit are intended to avoid these scenarios, taking into account that neard is configured to: (1)power the device up by default, and (2)not re-start the device in polling mode unless requested by the client (agl-service-nfc). - Check the adapter state before applying power or set the adapter in active polling mode as initiator. - Add neardal adapter callbacks to track status of the interface instead of using local variables. - Exit polling loop if the adapter is removed. - Update dbg macros to be more meaningful. Bug-AGL: SPEC-1976 The following changes are to increase safety measures around variables used on calls to/from neardal. - Test arguments in callback functions. - Install/remove tag callbacks in every iteration. - Match g_malloc'ed nfc_data_binding with g_free. Change-Id: If26d685a917633c9a0dd6997ad371db60a640517 Signed-off-by: Raquel Medina <raquel.medina@konsulko.com>
-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;