NFC: Handle LLCP UI frames
authorSamuel Ortiz <sameo@linux.intel.com>
Mon, 15 Oct 2012 14:14:37 +0000 (16:14 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Fri, 26 Oct 2012 16:26:50 +0000 (18:26 +0200)
UI (Unnumbered Information) frames are used for sending data over
connection less links.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
net/nfc/llcp/llcp.c
net/nfc/llcp/llcp.h

index 7f92a857b31965d6900a09d69098d02a8ba0ea10..a2da0a4f367d60b856ba9b05a49aaae8228f7efa 100644 (file)
@@ -720,6 +720,39 @@ static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len)
        return NULL;
 }
 
+static void nfc_llcp_recv_ui(struct nfc_llcp_local *local,
+                            struct sk_buff *skb)
+{
+       struct nfc_llcp_sock *llcp_sock;
+       struct nfc_llcp_ui_cb *ui_cb;
+       u8 dsap, ssap;
+
+       dsap = nfc_llcp_dsap(skb);
+       ssap = nfc_llcp_ssap(skb);
+
+       ui_cb = nfc_llcp_ui_skb_cb(skb);
+       ui_cb->dsap = dsap;
+       ui_cb->ssap = ssap;
+
+       printk("%s %d %d\n", __func__, dsap, ssap);
+
+       pr_debug("%d %d\n", dsap, ssap);
+
+       /* We're looking for a bound socket, not a client one */
+       llcp_sock = nfc_llcp_sock_get(local, dsap, LLCP_SAP_SDP);
+       if (llcp_sock == NULL || llcp_sock->sk.sk_type != SOCK_DGRAM)
+               return;
+
+       /* There is no sequence with UI frames */
+       skb_pull(skb, LLCP_HEADER_SIZE);
+       if (sock_queue_rcv_skb(&llcp_sock->sk, skb)) {
+               pr_err("receive queue is full\n");
+               skb_queue_head(&llcp_sock->tx_backlog_queue, skb);
+       }
+
+       nfc_llcp_sock_put(llcp_sock);
+}
+
 static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
                                  struct sk_buff *skb)
 {
@@ -1177,6 +1210,11 @@ static void nfc_llcp_rx_work(struct work_struct *work)
                pr_debug("SYMM\n");
                break;
 
+       case LLCP_PDU_UI:
+               pr_debug("UI\n");
+               nfc_llcp_recv_ui(local, skb);
+               break;
+
        case LLCP_PDU_CONNECT:
                pr_debug("CONNECT\n");
                nfc_llcp_recv_connect(local, skb);
index 1c0a66fab57036414333fe4ff622551f820f949d..e06d03571644d9e18dbb309f2a9222fcf1538c52 100644 (file)
@@ -124,6 +124,13 @@ struct nfc_llcp_sock {
        struct sock *parent;
 };
 
+struct nfc_llcp_ui_cb {
+       __u8 dsap;
+       __u8 ssap;
+};
+
+#define nfc_llcp_ui_skb_cb(__skb) ((struct nfc_llcp_ui_cb *)&((__skb)->cb[0]))
+
 #define nfc_llcp_sock(sk) ((struct nfc_llcp_sock *) (sk))
 #define nfc_llcp_dev(sk)  (nfc_llcp_sock((sk))->dev)