summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2013-11-18 01:48:15 +0100
committerSamuel Ortiz <sameo@linux.intel.com>2013-11-18 01:59:51 +0100
commitecc73a015d5670296febd3e07aae3301db3a4158 (patch)
tree891f5d0a683116ff58ab1ca61f5c194190a1cd10
parentb7f624308f1b5f3169d23f8607c5821bc38ad673 (diff)
downloadneard-ecc73a015d5670296febd3e07aae3301db3a4158.tar.gz
neard-ecc73a015d5670296febd3e07aae3301db3a4158.tar.bz2
neard-ecc73a015d5670296febd3e07aae3301db3a4158.zip
adapter: Catch polling errors
Receiving a NFC_EVENT_TARGETS_FOUND with a NULL payload means the driver entered an error state. This is handled by checking if the devices and targets arrays are empty from the GET_TARGET finish handler. In the polling error case, neard resets the adapter and starts polling again. The polling error handler runs asynchrounously for the D-Bus properties toggle to be exported properly.
-rw-r--r--src/adapter.c44
-rw-r--r--src/near.h1
-rw-r--r--src/netlink.c16
3 files changed, 59 insertions, 2 deletions
diff --git a/src/adapter.c b/src/adapter.c
index 52f11a6..98331a5 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -854,6 +854,50 @@ int __near_adapter_remove_target(uint32_t idx, uint32_t target_idx)
return 0;
}
+static gboolean poll_error(gpointer user_data)
+{
+ struct near_adapter *adapter = user_data;
+
+ DBG("adapter %d", adapter->idx);
+
+ /*
+ * Resettting the adapter upon polling errors.
+ * This could be handled through a configuration setting.
+ */
+ __near_netlink_adapter_enable(adapter->idx, false);
+ __near_netlink_adapter_enable(adapter->idx, true);
+
+ adapter_start_poll(adapter);
+
+ return FALSE;
+}
+
+int __near_adapter_get_targets_done(uint32_t idx)
+{
+ struct near_adapter *adapter;
+
+ DBG("idx %d", idx);
+
+ adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
+ if (!adapter)
+ return -ENODEV;
+
+ if (g_hash_table_size(adapter->devices) > 0)
+ return 0;
+
+ if (g_hash_table_size(adapter->tags) > 0)
+ return 0;
+
+ near_error("No targets found - Polling error");
+
+ adapter->polling = false;
+ polling_changed(adapter);
+
+ g_idle_add(poll_error, adapter);
+
+ return 0;
+}
+
int __near_adapter_add_device(uint32_t idx, uint8_t *nfcid, uint8_t nfcid_len)
{
struct near_adapter *adapter;
diff --git a/src/near.h b/src/near.h
index cf00675..c75aefe 100644
--- a/src/near.h
+++ b/src/near.h
@@ -86,6 +86,7 @@ int __near_adapter_add_target(uint32_t idx, uint32_t target_idx,
uint32_t protocols, uint16_t sens_res, uint8_t sel_res,
uint8_t *nfcid, uint8_t nfcid_len);
int __near_adapter_remove_target(uint32_t idx, uint32_t target_idx);
+int __near_adapter_get_targets_done(uint32_t idx);
int __near_adapter_add_device(uint32_t idx, uint8_t *nfcid, uint8_t nfcid_len);
int __near_adapter_remove_device(uint32_t idx);
int __near_adapter_set_dep_state(uint32_t idx, bool dep);
diff --git a/src/netlink.c b/src/netlink.c
index 936f65a..65e42a8 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -492,6 +492,17 @@ static int get_targets_handler(struct nl_msg *n, void *arg)
return 0;
}
+static int get_targets_finish_handler(struct nl_msg *n, void *arg)
+{
+ uint32_t adapter_idx;
+
+ DBG("");
+
+ adapter_idx = *((uint32_t *)arg);
+
+ return __near_adapter_get_targets_done(adapter_idx);
+}
+
static int nfc_netlink_event_targets_found(struct genlmsghdr *gnlh)
{
struct nlattr *attr[NFC_ATTR_MAX + 1];
@@ -526,8 +537,9 @@ static int nfc_netlink_event_targets_found(struct genlmsghdr *gnlh)
NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, adapter_idx);
- err = nl_send_msg(nfc_state->cmd_sock, msg,
- get_targets_handler, &adapter_idx);
+ err = __nl_send_msg(nfc_state->cmd_sock, msg,
+ get_targets_handler, get_targets_finish_handler,
+ &adapter_idx);
nla_put_failure:
nlmsg_free(msg);