summaryrefslogtreecommitdiffstats
path: root/net/nfc/llcp/llcp.c
diff options
context:
space:
mode:
authorThierry Escande <thierry.escande@linux.intel.com>2013-02-15 10:43:06 +0100
committerSamuel Ortiz <sameo@linux.intel.com>2013-03-10 23:14:54 +0100
commitd9b8d8e19b073096d3609bbd60f82148d128b555 (patch)
tree0888a7ff7367bc5efd1b5e1388bc59aab308451c /net/nfc/llcp/llcp.c
parente0ae7bac06ccb90bb0cf7a3362730b48c7d7f1a8 (diff)
NFC: llcp: Service Name Lookup netlink interface
This adds a netlink interface for service name lookup support. Multiple URIs can be passed nested into the NFC_ATTR_LLC_SDP attribute using the NFC_CMD_LLC_SDREQ netlink command. When the SNL reply is received, a NFC_EVENT_LLC_SDRES event is sent to the user space. URI and SAP tuples are passed back, nested into NFC_ATTR_LLC_SDP attribute. Signed-off-by: Thierry Escande <thierry.escande@linux.intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc/llcp/llcp.c')
-rw-r--r--net/nfc/llcp/llcp.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 30b61c1aa98..99e91106042 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -156,6 +156,7 @@ static void local_release(struct kref *ref)
cancel_work_sync(&local->rx_work);
cancel_work_sync(&local->timeout_work);
kfree_skb(local->rx_pending);
+ nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs);
kfree(local);
}
@@ -1147,6 +1148,7 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
struct nfc_llcp_sdp_tlv *sdp;
HLIST_HEAD(llc_sdres_list);
size_t sdres_tlvs_len;
+ HLIST_HEAD(nl_sdres_list);
dsap = nfc_llcp_dsap(skb);
ssap = nfc_llcp_ssap(skb);
@@ -1229,6 +1231,30 @@ add_snl:
hlist_add_head(&sdp->node, &llc_sdres_list);
break;
+ case LLCP_TLV_SDRES:
+ mutex_lock(&local->sdreq_lock);
+
+ pr_debug("LLCP_TLV_SDRES: searching tid %d\n", tlv[2]);
+
+ hlist_for_each_entry(sdp, &local->pending_sdreqs, node) {
+ if (sdp->tid != tlv[2])
+ continue;
+
+ sdp->sap = tlv[3];
+
+ pr_debug("Found: uri=%s, sap=%d\n",
+ sdp->uri, sdp->sap);
+
+ hlist_del(&sdp->node);
+
+ hlist_add_head(&sdp->node, &nl_sdres_list);
+
+ break;
+ }
+
+ mutex_unlock(&local->sdreq_lock);
+ break;
+
default:
pr_err("Invalid SNL tlv value 0x%x\n", type);
break;
@@ -1239,6 +1265,9 @@ add_snl:
}
exit:
+ if (!hlist_empty(&nl_sdres_list))
+ nfc_genl_llc_send_sdres(local->dev, &nl_sdres_list);
+
if (!hlist_empty(&llc_sdres_list))
nfc_llcp_send_snl_sdres(local, &llc_sdres_list, sdres_tlvs_len);
}
@@ -1426,6 +1455,9 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
local->remote_miu = LLCP_DEFAULT_MIU;
local->remote_lto = LLCP_DEFAULT_LTO;
+ mutex_init(&local->sdreq_lock);
+ INIT_HLIST_HEAD(&local->pending_sdreqs);
+
list_add(&local->list, &llcp_devices);
return 0;