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 
59 bool
60 nfc_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