diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2013-11-18 01:48:15 +0100 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-11-18 01:59:51 +0100 |
commit | ecc73a015d5670296febd3e07aae3301db3a4158 (patch) | |
tree | 891f5d0a683116ff58ab1ca61f5c194190a1cd10 | |
parent | b7f624308f1b5f3169d23f8607c5821bc38ad673 (diff) | |
download | neard-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.c | 44 | ||||
-rw-r--r-- | src/near.h | 1 | ||||
-rw-r--r-- | src/netlink.c | 16 |
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; @@ -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); |