NFC: Set target nfcid1 for all HCI reader A targets
authorEric Lapuyade <eric.lapuyade@intel.com>
Thu, 12 Jul 2012 18:27:54 +0000 (20:27 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 12 Jul 2012 18:48:41 +0000 (14:48 -0400)
Without the discovered target nfcid1 and its length set properly, type 2
tags detection fails with the pn544 as it checks for them from
pn544_hci_complete_target_discovered().

Signed-off-by: Eric Lapuyade <eric.lapuyade@intel.com>
Reported-by: Mathias Jeppsson <mathias.jeppsson@sonymobile.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/nfc/hci/core.c

index da6e039..4896ef1 100644 (file)
@@ -170,6 +170,7 @@ static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate)
        struct nfc_target *targets;
        struct sk_buff *atqa_skb = NULL;
        struct sk_buff *sak_skb = NULL;
+       struct sk_buff *uid_skb = NULL;
        int r;
 
        pr_debug("from gate %d\n", gate);
@@ -205,6 +206,19 @@ static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate)
                targets->sens_res = be16_to_cpu(*(u16 *)atqa_skb->data);
                targets->sel_res = sak_skb->data[0];
 
+               r = nfc_hci_get_param(hdev, NFC_HCI_RF_READER_A_GATE,
+                                     NFC_HCI_RF_READER_A_UID, &uid_skb);
+               if (r < 0)
+                       goto exit;
+
+               if (uid_skb->len == 0 || uid_skb->len > NFC_NFCID1_MAXSIZE) {
+                       r = -EPROTO;
+                       goto exit;
+               }
+
+               memcpy(targets->nfcid1, uid_skb->data, uid_skb->len);
+               targets->nfcid1_len = uid_skb->len;
+
                if (hdev->ops->complete_target_discovered) {
                        r = hdev->ops->complete_target_discovered(hdev, gate,
                                                                  targets);
@@ -240,6 +254,7 @@ exit:
        kfree(targets);
        kfree_skb(atqa_skb);
        kfree_skb(sak_skb);
+       kfree_skb(uid_skb);
 
        return r;
 }