NFC: Reserve LLCP ssap when replying to an SNL frame
authorSamuel Ortiz <sameo@linux.intel.com>
Mon, 15 Oct 2012 12:28:13 +0000 (14:28 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Fri, 26 Oct 2012 16:26:49 +0000 (18:26 +0200)
Replying to an SNL (Service Name Lookup) means that the other end of
the link can now rely on our answer (Which is an ssap) and thus we have
to reserve it.

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

index 2e826c0d1b9ac52a9681d24cc7426a992c468837..dd2cc0e48a1d40ce490ecd05e99e3714c5f59499 100644 (file)
@@ -1071,20 +1071,54 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
                        service_name = (char *) &tlv[3];
                        service_name_len = length - 1;
 
-                       pr_debug("Looking for %s\n", service_name);
+                       pr_debug("Looking for %.16s\n", service_name);
 
                        if (service_name_len == strlen("urn:nfc:sn:sdp") &&
                            !strncmp(service_name, "urn:nfc:sn:sdp",
                                     service_name_len)) {
                                sap = 1;
+                               goto send_snl;
+                       }
+
+                       llcp_sock = nfc_llcp_sock_from_sn(local, service_name,
+                                                         service_name_len);
+                       if (!llcp_sock) {
+                               sap = 0;
+                               goto send_snl;
+                       }
+
+                       /*
+                        * We found a socket but its ssap has not been reserved
+                        * yet. We need to assign it for good and send a reply.
+                        * The ssap will be freed when the socket is closed.
+                        */
+                       if (llcp_sock->ssap == LLCP_SDP_UNBOUND) {
+                               atomic_t *client_count;
+
+                               sap = nfc_llcp_reserve_sdp_ssap(local);
+
+                               pr_debug("Reserving %d\n", sap);
+
+                               if (sap == LLCP_SAP_MAX) {
+                                       sap = 0;
+                                       goto send_snl;
+                               }
+
+                               client_count =
+                                       &local->local_sdp_cnt[sap -
+                                                             LLCP_WKS_NUM_SAP];
+
+                               atomic_inc(client_count);
+
+                               llcp_sock->ssap = sap;
+                               llcp_sock->reserved_ssap = sap;
                        } else {
-                               llcp_sock =
-                                       nfc_llcp_sock_from_sn(local,
-                                                             service_name,
-                                                             service_name_len);
-                               sap = llcp_sock ? llcp_sock->ssap : 0;
+                               sap = llcp_sock->ssap;
                        }
 
+                       pr_debug("%p %d\n", llcp_sock, sap);
+
+               send_snl:
                        nfc_llcp_send_snl(local, tid, sap);
                        break;