00001 /*- 00002 * Public platform independent Near Field Communication (NFC) library examples 00003 * 00004 * Copyright (C) 2009, Roel Verdult 00005 * Copyright (C) 2010, Romuald Conty, Romain Tartière 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are met: 00009 * 1) Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * 2 )Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00017 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00019 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00020 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00021 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00023 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00024 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00025 * POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 * Note that this license only applies on the examples, NFC library itself is under LGPL 00028 * 00029 */ 00030 00031 #include "mifare.h" 00032 00033 #include <string.h> 00034 00035 #include <nfc/nfc.h> 00036 00050 bool 00051 nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param * pmp) 00052 { 00053 byte_t abtRx[265]; 00054 size_t szRx; 00055 size_t szParamLen; 00056 byte_t abtCmd[265]; 00057 bool bEasyFraming; 00058 00059 // Make sure we are dealing with a active device 00060 if (!pnd->bActive) 00061 return false; 00062 00063 abtCmd[0] = mc; // The MIFARE Classic command 00064 abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff) 00065 00066 switch (mc) { 00067 // Read and store command have no parameter 00068 case MC_READ: 00069 case MC_STORE: 00070 szParamLen = 0; 00071 break; 00072 00073 // Authenticate command 00074 case MC_AUTH_A: 00075 case MC_AUTH_B: 00076 szParamLen = sizeof (mifare_param_auth); 00077 break; 00078 00079 // Data command 00080 case MC_WRITE: 00081 szParamLen = sizeof (mifare_param_data); 00082 break; 00083 00084 // Value command 00085 case MC_DECREMENT: 00086 case MC_INCREMENT: 00087 case MC_TRANSFER: 00088 szParamLen = sizeof (mifare_param_value); 00089 break; 00090 00091 // Please fix your code, you never should reach this statement 00092 default: 00093 return false; 00094 break; 00095 } 00096 00097 // When available, copy the parameter bytes 00098 if (szParamLen) 00099 memcpy (abtCmd + 2, (byte_t *) pmp, szParamLen); 00100 00101 bEasyFraming = pnd->bEasyFraming; 00102 if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) { 00103 nfc_perror (pnd, "nfc_configure"); 00104 return false; 00105 } 00106 // Fire the mifare command 00107 if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx)) { 00108 if (pnd->iLastError == EINVRXFRAM) { 00109 // "Invalid received frame" AKA EINVRXFRAM, usual means we are 00110 // authenticated on a sector but the requested MIFARE cmd (read, write) 00111 // is not permitted by current acces bytes; 00112 // So there is nothing to do here. 00113 } else { 00114 nfc_perror (pnd, "nfc_initiator_transceive_bytes"); 00115 } 00116 nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming); 00117 return false; 00118 } 00119 if (!nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming)) { 00120 nfc_perror (pnd, "nfc_configure"); 00121 return false; 00122 } 00123 00124 // When we have executed a read command, copy the received bytes into the param 00125 if (mc == MC_READ) { 00126 if (szRx == 16) { 00127 memcpy (pmp->mpd.abtData, abtRx, 16); 00128 } else { 00129 return false; 00130 } 00131 } 00132 // Command succesfully executed 00133 return true; 00134 }