summaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2012-10-05 01:13:24 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2012-10-26 18:26:47 +0200
commitc43bb03d5a7df53684cfb2a1fed5ea20014c7056 (patch)
treef402223e4c7e235489b29a5b32c5b8653a8f648f /net/nfc
parent922239064bb39b4ed9329ffd9418c20f8d64cbbb (diff)
downloadlinux-stable-c43bb03d5a7df53684cfb2a1fed5ea20014c7056.tar.gz
linux-stable-c43bb03d5a7df53684cfb2a1fed5ea20014c7056.tar.bz2
linux-stable-c43bb03d5a7df53684cfb2a1fed5ea20014c7056.zip
NFC: Add SNL frame building routine
SNL (Service Name Lookup) frames are used to respond to SNL requests. This is needed for SDP implementation. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/llcp/commands.c46
-rw-r--r--net/nfc/llcp/llcp.h1
2 files changed, 47 insertions, 0 deletions
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c
index 5e33cba43936..6db280ddc4c8 100644
--- a/net/nfc/llcp/commands.c
+++ b/net/nfc/llcp/commands.c
@@ -420,6 +420,52 @@ error_tlv:
return err;
}
+int nfc_llcp_send_snl(struct nfc_llcp_local *local, u8 tid, u8 sap)
+{
+ struct sk_buff *skb;
+ struct nfc_dev *dev;
+ u8 *sdres_tlv = NULL, sdres_tlv_length, sdres[2];
+ u16 size = 0;
+
+ pr_debug("Sending SNL tid 0x%x sap 0x%x\n", tid, sap);
+
+ if (local == NULL)
+ return -ENODEV;
+
+ dev = local->dev;
+ if (dev == NULL)
+ return -ENODEV;
+
+ sdres[0] = tid;
+ sdres[1] = sap;
+ sdres_tlv = nfc_llcp_build_tlv(LLCP_TLV_SDRES, sdres, 0,
+ &sdres_tlv_length);
+ if (sdres_tlv == NULL)
+ return -ENOMEM;
+
+ size += LLCP_HEADER_SIZE;
+ size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
+ size += sdres_tlv_length;
+
+ skb = alloc_skb(size, GFP_KERNEL);
+ if (skb == NULL) {
+ kfree(sdres_tlv);
+ return -ENOMEM;
+ }
+
+ skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
+
+ skb = llcp_add_header(skb, LLCP_SAP_SDP, LLCP_SAP_SDP, LLCP_PDU_SNL);
+
+ memcpy(skb_put(skb, sdres_tlv_length), sdres_tlv, sdres_tlv_length);
+
+ skb_queue_tail(&local->tx_queue, skb);
+
+ kfree(sdres_tlv);
+
+ return 0;
+}
+
int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason)
{
struct sk_buff *skb;
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h
index fdb2d24e60bd..1c0a66fab570 100644
--- a/net/nfc/llcp/llcp.h
+++ b/net/nfc/llcp/llcp.h
@@ -209,6 +209,7 @@ int nfc_llcp_disconnect(struct nfc_llcp_sock *sock);
int nfc_llcp_send_symm(struct nfc_dev *dev);
int nfc_llcp_send_connect(struct nfc_llcp_sock *sock);
int nfc_llcp_send_cc(struct nfc_llcp_sock *sock);
+int nfc_llcp_send_snl(struct nfc_llcp_local *local, u8 tid, u8 sap);
int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason);
int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock);
int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,