libnfc 1.8.0
mifare.c
Go to the documentation of this file.
1/*-
2 * Free/Libre Near Field Communication (NFC) library
3 *
4 * Libnfc historical contributors:
5 * Copyright (C) 2009 Roel Verdult
6 * Copyright (C) 2009-2013 Romuald Conty
7 * Copyright (C) 2010-2012 Romain Tartière
8 * Copyright (C) 2010-2013 Philippe Teuwen
9 * Copyright (C) 2012-2013 Ludovic Rousseau
10 * See AUTHORS file for a more comprehensive list of contributors.
11 * Additional contributors of this file:
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 * 1) Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2 )Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Note that this license only applies on the examples, NFC library itself is under LGPL
34 *
35 */
40#include "mifare.h"
41
42#include <string.h>
43
44#include <nfc/nfc.h>
45
59bool
60nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp)
61{
62 uint8_t abtRx[265];
63 size_t szParamLen;
64 uint8_t abtCmd[265];
65 //bool bEasyFraming;
66
67 abtCmd[0] = mc; // The MIFARE Classic command
68 abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
69
70 switch (mc) {
71 // Read and store command have no parameter
72 case MC_READ:
73 case MC_STORE:
74 szParamLen = 0;
75 break;
76
77 // Authenticate command
78 case MC_AUTH_A:
79 case MC_AUTH_B:
80 szParamLen = sizeof(struct mifare_param_auth);
81 break;
82
83 // Data command
84 case MC_WRITE:
85 szParamLen = sizeof(struct mifare_param_data);
86 break;
87
88 // Value command
89 case MC_DECREMENT:
90 case MC_INCREMENT:
91 case MC_TRANSFER:
92 szParamLen = sizeof(struct mifare_param_value);
93 break;
94
95 // Please fix your code, you never should reach this statement
96 default:
97 return false;
98 }
99
100 // When available, copy the parameter bytes
101 if (szParamLen)
102 memcpy(abtCmd + 2, (uint8_t *) pmp, szParamLen);
103
104 // FIXME: Save and restore bEasyFraming
105 // bEasyFraming = nfc_device_get_property_bool (pnd, NP_EASY_FRAMING, &bEasyFraming);
106 if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true) < 0) {
107 nfc_perror(pnd, "nfc_device_set_property_bool");
108 return false;
109 }
110 // Fire the mifare command
111 int res;
112 if ((res = nfc_initiator_transceive_bytes(pnd, abtCmd, 2 + szParamLen, abtRx, sizeof(abtRx), -1)) < 0) {
113 if (res == NFC_ERFTRANS) {
114 // "Invalid received frame", usual means we are
115 // authenticated on a sector but the requested MIFARE cmd (read, write)
116 // is not permitted by current acces bytes;
117 // So there is nothing to do here.
118 } else {
119 nfc_perror(pnd, "nfc_initiator_transceive_bytes");
120 }
121 // XXX nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming);
122 return false;
123 }
124 /* XXX
125 if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming) < 0) {
126 nfc_perror (pnd, "nfc_device_set_property_bool");
127 return false;
128 }
129 */
130
131 // When we have executed a read command, copy the received bytes into the param
132 if (mc == MC_READ) {
133
134 //Check the length of response data, with PCSC reader, there have 2 bytes for SW value
135 if (res == 16 || res == (16 + 2)) {
136 memcpy(pmp->mpd.abtData, abtRx, 16);
137 } else {
138 return false;
139 }
140 }
141 // Command succesfully executed
142 return true;
143}
void nfc_perror(const nfc_device *pnd, const char *pcString)
Display the last error occured on a nfc_device.
Definition: nfc.c:1183
#define NFC_ERFTRANS
Definition: nfc.h:205
int nfc_initiator_transceive_bytes(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, int timeout)
Send data to target then retrieve data from target.
Definition: nfc.c:809
int nfc_device_set_property_bool(nfc_device *pnd, const nfc_property property, const bool bEnable)
Set a device's boolean-property value.
Definition: nfc.c:466
bool nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp)
Execute a MIFARE Classic Command.
Definition: mifare.c:60
provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
@ NP_EASY_FRAMING
Definition: nfc-types.h:136
libnfc interface
NFC device information.
Definition: nfc-internal.h:190