libnfc  1.7.1
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  break;
99  }
100 
101  // When available, copy the parameter bytes
102  if (szParamLen)
103  memcpy(abtCmd + 2, (uint8_t *) pmp, szParamLen);
104 
105  // FIXME: Save and restore bEasyFraming
106  // bEasyFraming = nfc_device_get_property_bool (pnd, NP_EASY_FRAMING, &bEasyFraming);
107  if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true) < 0) {
108  nfc_perror(pnd, "nfc_device_set_property_bool");
109  return false;
110  }
111  // Fire the mifare command
112  int res;
113  if ((res = nfc_initiator_transceive_bytes(pnd, abtCmd, 2 + szParamLen, abtRx, sizeof(abtRx), -1)) < 0) {
114  if (res == NFC_ERFTRANS) {
115  // "Invalid received frame", usual means we are
116  // authenticated on a sector but the requested MIFARE cmd (read, write)
117  // is not permitted by current acces bytes;
118  // So there is nothing to do here.
119  } else {
120  nfc_perror(pnd, "nfc_initiator_transceive_bytes");
121  }
122  // XXX nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming);
123  return false;
124  }
125  /* XXX
126  if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming) < 0) {
127  nfc_perror (pnd, "nfc_device_set_property_bool");
128  return false;
129  }
130  */
131 
132  // When we have executed a read command, copy the received bytes into the param
133  if (mc == MC_READ) {
134  if (res == 16) {
135  memcpy(pmp->mpd.abtData, abtRx, 16);
136  } else {
137  return false;
138  }
139  }
140  // Command succesfully executed
141  return true;
142 }
nfc_device
NFC device information.
Definition: nfc-internal.h:190
nfc_initiator_mifare_cmd
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
nfc_initiator_transceive_bytes
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:764
nfc_perror
void nfc_perror(const nfc_device *pnd, const char *pcString)
Display the last error occured on a nfc_device.
Definition: nfc.c:1138
NP_EASY_FRAMING
@ NP_EASY_FRAMING
Definition: nfc-types.h:135
NFC_ERFTRANS
#define NFC_ERFTRANS
Definition: nfc.h:206
mifare.h
provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
nfc_device_set_property_bool
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:426
nfc.h
libnfc interface