I can read the UID, ATQA, and SAK from my NFC tag. But I don't really know what ATQA and SAK means and how can I change the value of those things?
I also want to know how to read and write the ndef message on my nfc tag. How can I do that? Do libnfc capable of doing that?
I have done some research on this website http://www.libnfc.org/api/examples_page.html but I don't really understand all of them. I've tried every example program provided by the lib-nfc, the only one working is nfc-poll and quick_start_example1 and 2 which is actually doing the same thing as the nfc-poll.
Can anyone help?
Edit 2015-08-07 :
i have done searching all over the web so far this is what i have found useful
http://matt.bionicmessage.net/blog/2010 ... h%20course
it looks like this guy successfully authenticate the key to read the data block for NFC card but this guy is using different files/library not from libnfc
so i modified the quick_start_example1.c from libnfc (libnfc-1.7.1/examples/doc/quick_start_example1.c) and i make this new code
Code: Select all
/**
* @file quick_start_example1.c
* @brief Quick start example that presents how to use libnfc
*/
/**
* this code is edited from quick_start_example1
* this code doesnt work.
*/
// To compile this simple example:
// $ gcc -o quick_start_example1 quick_start_example1.c -lnfc
#include <stdlib.h>
#include <nfc/nfc.h> //located on libnfc-1.7.1/include/nfc/nfc.h
#include <string.h>
//#include <nfc/nfc-types.h> //located on libnfc-1.7.1/include/nfc/nfc-types.h
#include </home/pi/libnfc-1.7.1/utils/mifare.h>
static mifare_param mp; //addition
nfc_target_info nti; //declare nfc_target_info as nti for ease of use
nfc_device *pnd;
//declaring keys 6x8 = 48 bit
static uint8_t keys[] = {
0xff,0xff,0xff,0xff,0xff,0xff,
0xd3,0xf7,0xd3,0xf7,0xd3,0xf7,
0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,
0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,
0x4d,0x3a,0x99,0xc3,0x51,0xdd,
0x1a,0x98,0x2c,0x7e,0x45,0x9a,
0xaa,0xbb,0xcc,0xdd,0xee,0xff,
0x00,0x00,0x00,0x00,0x00,0x00
};
//function to authenticate
static bool
authenticate(int block, int keynum, bool keyB) {
memcpy(mp.mpa.abtAuthUid,nti.nai.abtUid,4);
memcpy(mp.mpa.abtKey, &keys[keynum], 6);
bool res = nfc_initiator_mifare_cmd(pnd, (keyB ? MC_AUTH_B : MC_AUTH_A), block, &mp);
if (res) {
printf("Authentication succcessful on block %d\n",block);
} else {
printf("Authentication failed on block %d\n",block);
}
return res;
}
//function to readblock
void readblocks(int start, int end) {
int block;
for (block=start; block<(end+1); block++) {
bool res = nfc_initiator_mifare_cmd(pnd, MC_READ, block, &mp);
if (res) {
printf("Block %d data: ",block);
//print_hex(mp.mpd.abtData,16);
} else {
printf("Reading block %d failed\n",block);
}
}
}
//function print_hex to show data on terminal
static void print_hex(const uint8_t *pbtData, const size_t szBytes)
{
size_t szPos;
for (szPos = 0; szPos < szBytes; szPos++) {
printf("%02x ", pbtData[szPos]);
}
printf("\n");
}
//function main
int
main(int argc, const char *argv[])
{
//nfc_device *pnd; //this initialization is moved to the top of the file
nfc_target nt;
// Allocate only a pointer to nfc_context
nfc_context *context;
// Initialize libnfc and set the nfc_context
nfc_init(&context);
if (context == NULL) {
printf("Unable to init libnfc (malloc)\n");
exit(EXIT_FAILURE);
}
// Display libnfc version
const char *acLibnfcVersion = nfc_version();
(void)argc;
printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
// Open, using the first available NFC device which can be in order of selection:
// - default device specified using environment variable or
// - first specified device in libnfc.conf (/etc/nfc) or
// - first specified device in device-configuration directory (/etc/nfc/devices.d) or
// - first auto-detected (if feature is not disabled in libnfc.conf) device
pnd = nfc_open(context, NULL);
if (pnd == NULL) {
printf("ERROR: %s\n", "Unable to open NFC device.");
exit(EXIT_FAILURE);
}
// Set opened NFC device to initiator mode
if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init");
exit(EXIT_FAILURE);
}
printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));
// Poll for a ISO14443A (MIFARE) tag
const nfc_modulation nmMifare = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) > 0) {
printf("The following (NFC) ISO14443A tag was found:\n");
printf(" ATQA (SENS_RES): ");
print_hex(nt.nti.nai.abtAtqa, 2);
printf(" UID (NFCID%c): ", (nt.nti.nai.abtUid[0] == 0x08 ? '3' : '1'));
print_hex(nt.nti.nai.abtUid, nt.nti.nai.szUidLen);
printf(" SAK (SEL_RES): ");
print_hex(&nt.nti.nai.btSak, 1);
if (nt.nti.nai.szAtsLen) {
printf(" ATS (ATR): ");
print_hex(nt.nti.nai.abtAts, nt.nti.nai.szAtsLen);
}
//try to read blocks
} else {
goto DISCONNECT;
}
// Try to login to sector 0. Use the default key FFFF, for key A
bool authenticated = authenticate(3,0,false);
if (!authenticated) {
goto DISCONNECT;
}
readblocks(0,3); //read block 0 untill 3 (4 blocks)
DISCONNECT:
// Disconnect from NFC device
nfc_disconnect(pnd);
return EXIT_SUCCESS;
//compare the UID from nt.nti.nai.abtUid with stored UID
const uint8_t winner[] = { 0x9e, 0x74, 0x03, 0x0a};
if (memcmp(nt.nti.nai.abtUid, winner, 4) == 0) {
printf("UID matched\n");
}
//nt.nti.nai.abtUid
//nt = nfc_target
//nti = nfc_target info
//nai = nfc_iso14443a_info nai <- all this is set on nfc-types.h
//abtUid = UID of the nfc tag
//template of memcmp
//int memcmp(const void *str1, const void *str2, size_t n)
//try to read the data block
//template to read data block
//uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data);
//print the ats
printf(" Test ATS : ");
print_hex(nt.nti.nai.abtAts, 254);
//print dep info
printf(" DEP abtNFCID3 : ");
print_hex(nt.nti.ndi.abtNFCID3 , 11);
// Close NFC device
nfc_close(pnd);
// Release the context
nfc_exit(context);
exit(EXIT_SUCCESS);
}
Code: Select all
gcc -o quick_start_example4 quick_start_example4.c -lnfcCode: Select all
/usr/bin/ld:cannot find -lnfc
collect2: ld returned 1 exit statusEdit 2015-07-09
Turns out there is something wrong with the script i use to compile the code. I changed it with my script that has been successful to compile quick_start_example3.c and now the quick_start_example4.c doesn't show
Code: Select all
/usr/bin/ld:cannot find -lnfcCode: Select all
/tmp/cc3wcb4X.o: In function `authenticate':
quick_start_example3.c:(.text+0xa0): undefined reference to `nfc_initiator_mifare_cmd'
/tmp/cc3wcb4X.o: In function `readblocks':
quick_start_example3.c:(.text+0x144): undefined reference to `nfc_initiator_mifare_cmd'
/tmp/cc3wcb4X.o: In function `main':
quick_start_example3.c:(.text+0x498): undefined reference to `nfc_disconnect'
collect2: ld returned 1 exit status
Turns out we can read mifare classic tag PN532 using libnfc-1.7.1
after setting up from http://blog.iteadstudio.com/raspberry-p ... th-libnfc/
we can create hex dump file using this :
Code: Select all
nfc-mfclassic r b dump.mfdr means read, b means using key b, dump.mfd is a file created containing sectors, blocks, keys, and data stored on the card
we read the .mfd filetypes using command
Code: Select all
xxd dump.mfdCode: Select all
sudo apt-get install xxd