Skip to content

Commit

Permalink
NFC: llcp: Add cleanup support for unreplied SNL requests
Browse files Browse the repository at this point in the history
If the remote LLC doesn't reply in time to our SNL requests we remove
them from the list of pending requests. The timeout is fixed to an
arbitrary value of 3 times remote_lto.

When not replied, the local LLC broadcasts NFC_EVENT_LLC_SDRES nl events for
the concerned uris with sap values set to LLCP_SDP_UNBOUND (which is 65).

Signed-off-by: Thierry Escande <thierry.escande@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
  • Loading branch information
Thierry Escande authored and Samuel Ortiz committed Mar 10, 2013
1 parent d9b8d8e commit 40213fa
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
6 changes: 6 additions & 0 deletions net/nfc/llcp/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
sdreq->uri = sdreq->tlv + 3;
memcpy(sdreq->uri, uri, uri_len);

sdreq->time = jiffies;

INIT_HLIST_NODE(&sdreq->node);

return sdreq;
Expand Down Expand Up @@ -571,6 +573,10 @@ int nfc_llcp_send_snl_sdreq(struct nfc_llcp_local *local,

mutex_lock(&local->sdreq_lock);

if (hlist_empty(&local->pending_sdreqs))
mod_timer(&local->sdreq_timer,
jiffies + msecs_to_jiffies(3 * local->remote_lto));

hlist_for_each_entry_safe(sdreq, n, tlv_list, node) {
pr_debug("tid %d for %s\n", sdreq->tid, sdreq->uri);

Expand Down
47 changes: 47 additions & 0 deletions net/nfc/llcp/llcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ static void local_release(struct kref *ref)
cancel_work_sync(&local->rx_work);
cancel_work_sync(&local->timeout_work);
kfree_skb(local->rx_pending);
del_timer_sync(&local->sdreq_timer);
cancel_work_sync(&local->sdreq_timeout_work);
nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs);
kfree(local);
}
Expand Down Expand Up @@ -224,6 +226,47 @@ static void nfc_llcp_symm_timer(unsigned long data)
schedule_work(&local->timeout_work);
}

static void nfc_llcp_sdreq_timeout_work(struct work_struct *work)
{
unsigned long time;
HLIST_HEAD(nl_sdres_list);
struct hlist_node *n;
struct nfc_llcp_sdp_tlv *sdp;
struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
sdreq_timeout_work);

mutex_lock(&local->sdreq_lock);

time = jiffies - msecs_to_jiffies(3 * local->remote_lto);

hlist_for_each_entry_safe(sdp, n, &local->pending_sdreqs, node) {
if (time_after(sdp->time, time))
continue;

sdp->sap = LLCP_SDP_UNBOUND;

hlist_del(&sdp->node);

hlist_add_head(&sdp->node, &nl_sdres_list);
}

if (!hlist_empty(&local->pending_sdreqs))
mod_timer(&local->sdreq_timer,
jiffies + msecs_to_jiffies(3 * local->remote_lto));

mutex_unlock(&local->sdreq_lock);

if (!hlist_empty(&nl_sdres_list))
nfc_genl_llc_send_sdres(local->dev, &nl_sdres_list);
}

static void nfc_llcp_sdreq_timer(unsigned long data)
{
struct nfc_llcp_local *local = (struct nfc_llcp_local *) data;

schedule_work(&local->sdreq_timeout_work);
}

struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev)
{
struct nfc_llcp_local *local, *n;
Expand Down Expand Up @@ -1457,6 +1500,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)

mutex_init(&local->sdreq_lock);
INIT_HLIST_HEAD(&local->pending_sdreqs);
init_timer(&local->sdreq_timer);
local->sdreq_timer.data = (unsigned long) local;
local->sdreq_timer.function = nfc_llcp_sdreq_timer;
INIT_WORK(&local->sdreq_timeout_work, nfc_llcp_sdreq_timeout_work);

list_add(&local->list, &llcp_devices);

Expand Down
4 changes: 4 additions & 0 deletions net/nfc/llcp/llcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ struct nfc_llcp_sdp_tlv {
u8 tid;
u8 sap;

unsigned long time;

struct hlist_node node;
};

Expand Down Expand Up @@ -99,6 +101,8 @@ struct nfc_llcp_local {

struct mutex sdreq_lock;
struct hlist_head pending_sdreqs;
struct timer_list sdreq_timer;
struct work_struct sdreq_timeout_work;
u8 sdreq_next_tid;

/* sockets array */
Expand Down

0 comments on commit 40213fa

Please sign in to comment.