aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/llcp
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2012-06-26 10:13:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-07-09 16:42:20 -0400
commit5c0560b7a5c662ce5fef6ddd52f7bc8d38ad1907 (patch)
treec3ab7675d243ff884a59271463c089daa5654930 /net/nfc/llcp
parent8f50020ed9b81ba909ce9573f9d05263cdebf502 (diff)
NFC: Handle LLCP Disconnected Mode frames
When receiving such frame, the sockets waiting for a connection to finish should be woken up. Connecting to an unbound LLCP service will trigger a DM as a response. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc/llcp')
-rw-r--r--net/nfc/llcp/llcp.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 6094a2099bd6..f3bc0a9efb37 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -958,6 +958,45 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb)
958 nfc_llcp_sock_put(llcp_sock); 958 nfc_llcp_sock_put(llcp_sock);
959} 959}
960 960
961static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb)
962{
963 struct nfc_llcp_sock *llcp_sock;
964 struct sock *sk;
965 u8 dsap, ssap, reason;
966
967 dsap = nfc_llcp_dsap(skb);
968 ssap = nfc_llcp_ssap(skb);
969 reason = skb->data[2];
970
971 pr_debug("%d %d reason %d\n", ssap, dsap, reason);
972
973 switch (reason) {
974 case LLCP_DM_NOBOUND:
975 case LLCP_DM_REJ:
976 llcp_sock = nfc_llcp_connecting_sock_get(local, dsap);
977 break;
978
979 default:
980 llcp_sock = nfc_llcp_sock_get(local, dsap, ssap);
981 break;
982 }
983
984 if (llcp_sock == NULL) {
985 pr_err("Invalid DM\n");
986 return;
987 }
988
989 sk = &llcp_sock->sk;
990
991 sk->sk_err = ENXIO;
992 sk->sk_state = LLCP_CLOSED;
993 sk->sk_state_change(sk);
994
995 nfc_llcp_sock_put(llcp_sock);
996
997 return;
998}
999
961static void nfc_llcp_rx_work(struct work_struct *work) 1000static void nfc_llcp_rx_work(struct work_struct *work)
962{ 1001{
963 struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, 1002 struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
@@ -1001,6 +1040,11 @@ static void nfc_llcp_rx_work(struct work_struct *work)
1001 nfc_llcp_recv_cc(local, skb); 1040 nfc_llcp_recv_cc(local, skb);
1002 break; 1041 break;
1003 1042
1043 case LLCP_PDU_DM:
1044 pr_debug("DM\n");
1045 nfc_llcp_recv_dm(local, skb);
1046 break;
1047
1004 case LLCP_PDU_I: 1048 case LLCP_PDU_I:
1005 case LLCP_PDU_RR: 1049 case LLCP_PDU_RR:
1006 case LLCP_PDU_RNR: 1050 case LLCP_PDU_RNR: