/* * Returns: * <= 0: driver handled the data exchange * 1: driver doesn't especially handle, please do standard processing */ static int microread_im_transceive(struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) { struct microread_info *info = nfc_hci_get_clientdata(hdev); u8 control_bits; u16 crc; pr_info("data exchange to gate 0x%x\n", target->hci_reader_gate); if (target->hci_reader_gate == MICROREAD_GATE_ID_P2P_INITIATOR) { *skb_push(skb, 1) = 0; return nfc_hci_send_event(hdev, target->hci_reader_gate, MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF, skb->data, skb->len); } switch (target->hci_reader_gate) { case MICROREAD_GATE_ID_MREAD_ISO_A: control_bits = 0xCB; break; case MICROREAD_GATE_ID_MREAD_ISO_A_3: control_bits = 0xCB; break; case MICROREAD_GATE_ID_MREAD_ISO_B: control_bits = 0xCB; break; case MICROREAD_GATE_ID_MREAD_NFC_T1: control_bits = 0x1B; crc = crc_ccitt(0xffff, skb->data, skb->len); crc = ~crc; *skb_put(skb, 1) = crc & 0xff; *skb_put(skb, 1) = crc >> 8; break; case MICROREAD_GATE_ID_MREAD_NFC_T3: control_bits = 0xDB; break; default: pr_info("Abort im_transceive to invalid gate 0x%x\n", target->hci_reader_gate); return 1; } *skb_push(skb, 1) = control_bits; info->async_cb_type = MICROREAD_CB_TYPE_READER_ALL; info->async_cb = cb; info->async_cb_context = cb_context; return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, MICROREAD_CMD_MREAD_EXCHANGE, skb->data, skb->len, microread_im_transceive_cb, info); }
/* * Returns: * <= 0: driver handled the data exchange * 1: driver doesn't especially handle, please do standard processing */ static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); pr_info(DRIVER_DESC ": %s for gate=%d len=%d\n", __func__, target->hci_reader_gate, skb->len); switch (target->hci_reader_gate) { case ST21NFCA_RF_READER_F_GATE: if (target->supported_protocols == NFC_PROTO_NFC_DEP_MASK) return st21nfca_im_send_dep_req(hdev, skb); *(u8 *)skb_push(skb, 1) = 0x1a; return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, ST21NFCA_WR_XCHG_DATA, skb->data, skb->len, cb, cb_context); case ST21NFCA_RF_READER_14443_3_A_GATE: *(u8 *)skb_push(skb, 1) = 0x1a; /* CTR, see spec:10.2.2.1 */ return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, ST21NFCA_WR_XCHG_DATA, skb->data, skb->len, cb, cb_context); case ST21NFCA_RF_READER_ISO15693_GATE: info->async_cb_type = ST21NFCA_CB_TYPE_READER_ISO15693; info->async_cb = cb; info->async_cb_context = cb_context; *(u8 *)skb_push(skb, 1) = 0x17; return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, ST21NFCA_WR_XCHG_DATA, skb->data, skb->len, st21nfca_hci_data_exchange_cb, info); break; default: return 1; } }
/* * Returns: * <= 0: driver handled the data exchange * 1: driver doesn't especially handle, please do standard processing */ static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) { struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); pr_debug(DRIVER_DESC ": %s for gate=%d\n", __func__, target->hci_reader_gate); switch (target->hci_reader_gate) { case NFC_HCI_RF_READER_A_GATE: if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { /* * It seems that pn544 is inverting key and UID for * MIFARE authentication commands. */ if (skb->len == MIFARE_CMD_LEN && (skb->data[0] == MIFARE_CMD_AUTH_KEY_A || skb->data[0] == MIFARE_CMD_AUTH_KEY_B)) { u8 uid[MIFARE_UID_LEN]; u8 *data = skb->data + MIFARE_CMD_HEADER; memcpy(uid, data + MIFARE_KEY_LEN, MIFARE_UID_LEN); memmove(data + MIFARE_UID_LEN, data, MIFARE_KEY_LEN); memcpy(data, uid, MIFARE_UID_LEN); } return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, PN544_MIFARE_CMD, skb->data, skb->len, cb, cb_context); } else return 1; case PN544_RF_READER_F_GATE: *skb_push(skb, 1) = 0; *skb_push(skb, 1) = 0; info->async_cb_type = PN544_CB_TYPE_READER_F; info->async_cb = cb; info->async_cb_context = cb_context; return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, PN544_FELICA_RAW, skb->data, skb->len, pn544_hci_data_exchange_cb, info); case PN544_RF_READER_JEWEL_GATE: return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, PN544_JEWEL_RAW_CMD, skb->data, skb->len, cb, cb_context); case PN544_RF_READER_NFCIP1_INITIATOR_GATE: *skb_push(skb, 1) = 0; return nfc_hci_send_event(hdev, target->hci_reader_gate, PN544_HCI_EVT_SND_DATA, skb->data, skb->len); default: return 1; } }