static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target) { int r, len; u16 atqa; u8 sak; u8 uid[NFC_NFCID1_MAXSIZE]; switch (gate) { case ST21NFCA_RF_READER_F_GATE: target->supported_protocols = NFC_PROTO_FELICA_MASK; break; case ST21NFCA_RF_READER_14443_3_A_GATE: /* ISO14443-3 type 1 or 2 tags */ r = st21nfca_get_iso14443_3_atqa(hdev, &atqa); if (r < 0) return r; if (atqa == 0x000c) { target->supported_protocols = NFC_PROTO_JEWEL_MASK; target->sens_res = 0x0c00; } else { r = st21nfca_get_iso14443_3_sak(hdev, &sak); if (r < 0) return r; r = st21nfca_get_iso14443_3_uid(hdev, uid, &len); if (r < 0) return r; target->supported_protocols = nfc_hci_sak_to_protocol(sak); if (target->supported_protocols == 0xffffffff) return -EPROTO; target->sens_res = atqa; target->sel_res = sak; memcpy(target->nfcid1, uid, len); target->nfcid1_len = len; } break; case ST21NFCA_RF_READER_ISO15693_GATE: target->supported_protocols = NFC_PROTO_ISO15693_MASK; r = st21nfca_get_iso15693_inventory(hdev, target); if (r < 0) return r; break; default: return -EPROTO; } return 0; }
static void microread_target_discovered(struct nfc_hci_dev *hdev, u8 gate, struct sk_buff *skb) { struct nfc_target *targets; int r = 0; pr_info("target discovered to gate 0x%x\n", gate); targets = kzalloc(sizeof(struct nfc_target), GFP_KERNEL); if (targets == NULL) { r = -ENOMEM; goto exit; } targets->hci_reader_gate = gate; switch (gate) { case MICROREAD_GATE_ID_MREAD_ISO_A: targets->supported_protocols = nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A_SAK]); targets->sens_res = be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A_ATQA]); targets->sel_res = skb->data[MICROREAD_EMCF_A_SAK]; targets->nfcid1_len = skb->data[MICROREAD_EMCF_A_LEN]; if (targets->nfcid1_len > sizeof(targets->nfcid1)) { r = -EINVAL; goto exit_free; } memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A_UID], targets->nfcid1_len); break; case MICROREAD_GATE_ID_MREAD_ISO_A_3: targets->supported_protocols = nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A3_SAK]); targets->sens_res = be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A3_ATQA]); targets->sel_res = skb->data[MICROREAD_EMCF_A3_SAK]; targets->nfcid1_len = skb->data[MICROREAD_EMCF_A3_LEN]; if (targets->nfcid1_len > sizeof(targets->nfcid1)) { r = -EINVAL; goto exit_free; } memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A3_UID], targets->nfcid1_len); break; case MICROREAD_GATE_ID_MREAD_ISO_B: targets->supported_protocols = NFC_PROTO_ISO14443_B_MASK; memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_B_UID], 4); targets->nfcid1_len = 4; break; case MICROREAD_GATE_ID_MREAD_NFC_T1: targets->supported_protocols = NFC_PROTO_JEWEL_MASK; targets->sens_res = le16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_T1_ATQA]); memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T1_UID], 4); targets->nfcid1_len = 4; break; case MICROREAD_GATE_ID_MREAD_NFC_T3: targets->supported_protocols = NFC_PROTO_FELICA_MASK; memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T3_UID], 8); targets->nfcid1_len = 8; break; default: pr_info("discard target discovered to gate 0x%x\n", gate); goto exit_free; } r = nfc_targets_found(hdev->ndev, targets, 1); exit_free: kfree(targets); exit: kfree_skb(skb); if (r) pr_err("Failed to handle discovered target err=%d", r); }