Move examples into src/examples subdirectory.

Change examples names to nfc-* (or nfcip-*).
This commit is contained in:
Romuald Conty 2009-10-06 08:32:50 +00:00
parent de537473a0
commit 6aae96e1e1
18 changed files with 37 additions and 33 deletions

35
src/examples/Makefile.am Normal file
View file

@ -0,0 +1,35 @@
bin_PROGRAMS = nfc-anticol nfc-list nfc-mftool nfc-mfultool nfc-relay nfc-emulate nfcip-target nfcip-initiator
# set the include path found by configure
INCLUDES= $(all_includes)
AM_CFLAGS = -I$(top_srcdir)/src
nfc_anticol_SOURCES = nfc-anticol.c
nfc_anticol_LDADD = $(top_builddir)/src/libnfc.la
nfc_list_SOURCES = nfc-list.c
nfc_list_LDADD = $(top_builddir)/src/libnfc.la
nfc_mfultool_SOURCES = nfc-mfultool.c mifareultag.h
nfc_mfultool_LDADD = $(top_builddir)/src/libnfc.la
nfc_mftool_SOURCES = nfc-mftool.c mifaretag.h
nfc_mftool_LDADD = $(top_builddir)/src/libnfc.la
nfc_relay_SOURCES = nfc-relay.c
nfc_relay_LDADD = $(top_builddir)/src/libnfc.la
nfc_emulate_SOURCES = nfc-emulate.c
nfc_emulate_LDADD = $(top_builddir)/src/libnfc.la
nfcip_target_SOURCES = nfcip-target.c
nfcip_target_LDADD = $(top_builddir)/src/libnfc.la
nfcip_initiator_SOURCES = nfcip-initiator.c
nfcip_initiator_LDADD = $(top_builddir)/src/libnfc.la
dist_man_MANS = nfc-anticol.1 nfc-emulate.1 nfc-list.1 nfc-mftool.1 nfc-relay.1
#dist_man_MANS = $(man_MANS)
#EXTRA_DIST = $(man_MANS)

54
src/examples/mifaretag.h Normal file
View file

@ -0,0 +1,54 @@
/*
Public platform independent Near Field Communication (NFC) library
Copyright (C) 2009, Roel Verdult
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef _LIBNFC_MIFARE_TAG_H_
#define _LIBNFC_MIFARE_TAG_H_
#include "defines.h"
typedef struct {
byte_t abtUID[4];
byte_t btBCC;
byte_t btUnknown;
byte_t abtATQA[2];
byte_t abtUnknown[8];
} mifare_block_manufacturer;
typedef struct {
byte_t abtData[16];
} mifare_block_data;
typedef struct {
byte_t abtKeyA[6];
byte_t abtAccessBits[4];
byte_t abtKeyB[6];
} mifare_block_trailer;
typedef union {
mifare_block_manufacturer mbm;
mifare_block_data mbd;
mifare_block_trailer mbt;
} mifare_block;
typedef struct {
mifare_block amb[256];
} mifare_tag;
#endif // _LIBNFC_MIFARE_TAG_H_

View file

@ -0,0 +1,49 @@
/*
Public platform independent Near Field Communication (NFC) library
Copyright (C) 2009, Roel Verdult
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef _LIBNFC_MIFARE_UL_TAG_H_
#define _LIBNFC_MIFARE_UL_TAG_H_
#include "defines.h"
typedef struct {
byte_t sn0[3];
byte_t btBCC0;
byte_t sn1[4];
byte_t btBCC1;
byte_t internal;
byte_t lock[2];
byte_t otp[4];
} mifareul_block_manufacturer;
typedef struct {
byte_t abtData[16];
} mifareul_block_data;
typedef union {
mifareul_block_manufacturer mbm;
mifareul_block_data mbd;
} mifareul_block;
typedef struct {
mifareul_block amb[4];
} mifareul_tag;
#endif // _LIBNFC_MIFARE_UL_TAG_H_

View file

@ -0,0 +1,30 @@
.TH NFC-ANTICOL 1 "June 26, 2009"
.SH NAME
nfc-anticol \- Demonstration NFC anti-collison command line tool based on libnfc
.SH SYNOPSIS
.B nfc-anticol
.SH DESCRIPTION
.B nfc-anticol
is an anti-collision demonstration tool for ISO/IEC 14443-A tags, performed
by custom constructed frames. The first frame must be a short frame which
is only 7 bits long. Commercial SDK's often don't support a feature to send
frames that are not a multiple of 8 bits (1 byte) long.
This makes it impossible to do the anti-collision yourself.
The developer has to rely on closed proprietary software and should hope it does not contain vulnerabilities during the anti-collision phase.
Performing the anti-collision using custom frames could protect against a malicious tag that, for example, violates the standard by sending frames with unsupported lengths.
.SH BUGS
Please report any bugs on the
.B libnfc
forum at
.BR http://www.libnfc.org/community/ "."
.SH LICENCE
.B libnfc
and
.B nfc-tools
are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS
Roel Verdult <roel@libnfc.org>
.PP
This manual page was written by Romuald Conty <romuald.conty@free.fr>.
It is licensed under the terms of the GNU GPL (version 2 or later).

199
src/examples/nfc-anticol.c Normal file
View file

@ -0,0 +1,199 @@
/*
Public platform independent Near Field Communication (NFC) library
Copyright (C) 2009, Roel Verdult
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "libnfc.h"
#include "messages.h"
#define SAK_FLAG_ATS_SUPPORTED 0x20
static byte_t abtRx[MAX_FRAME_LEN];
static size_t szRxBits;
static size_t szRxLen;
static byte_t abtUid[10];
static size_t szUidLen = 4;
static dev_info* pdi;
bool quiet_output = false;
// ISO14443A Anti-Collision Commands
byte_t abtReqa [1] = { 0x26 };
byte_t abtSelectAll [2] = { 0x93,0x20 };
byte_t abtSelectTag [9] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
byte_t abtRats [4] = { 0xe0,0x50,0xbc,0xa5 };
byte_t abtHalt [4] = { 0x50,0x00,0x57,0xcd };
bool transmit_bits(const byte_t* pbtTx, const size_t szTxBits)
{
// Show transmitted command
if(!quiet_output)
{
printf("R: ");
print_hex_bits(pbtTx,szTxBits);
}
// Transmit the bit frame command, we don't use the arbitrary parity feature
if (!nfc_initiator_transceive_bits(pdi,pbtTx,szTxBits,NULL,abtRx,&szRxBits,NULL)) return false;
// Show received answer
if(!quiet_output)
{
printf("T: ");
print_hex_bits(abtRx,szRxBits);
}
// Succesful transfer
return true;
}
bool transmit_bytes(const byte_t* pbtTx, const size_t szTxLen)
{
// Show transmitted command
if(!quiet_output)
{
printf("R: ");
print_hex(pbtTx,szTxLen);
}
// Transmit the command bytes
if (!nfc_initiator_transceive_bytes(pdi,pbtTx,szTxLen,abtRx,&szRxLen)) return false;
// Show received answer
if(!quiet_output)
{
printf("T: ");
print_hex(abtRx,szRxLen);
}
// Succesful transfer
return true;
}
void print_usage(char* argv[])
{
printf("Usage: %s [OPTIONS]\n", argv[0]);
printf("Options:\n");
printf("\t-h\tHelp. Print this message.\n");
printf("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
}
int main(int argc,char* argv[])
{
int arg;
// Get commandline options
for (arg=1;arg<argc;arg++) {
if (0 == strcmp(argv[arg], "-h")) {
print_usage(argv);
return 0;
} else if (0 == strcmp(argv[arg], "-q")) {
INFO("Quiet mode.");
quiet_output = true;
} else {
ERR("%s is not supported option.", argv[arg]);
print_usage(argv);
return -1;
}
}
// Try to open the NFC reader
pdi = nfc_connect(NULL);
if (!pdi)
{
printf("Error connecting NFC reader\n");
return 1;
}
nfc_initiator_init(pdi);
// Drop the field for a while
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
// Configure the CRC and Parity settings
nfc_configure(pdi,DCO_HANDLE_CRC,false);
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
// Enable field so more power consuming cards can power themselves up
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
printf("\nConnected to NFC reader: %s\n\n",pdi->acName);
// Send the 7 bits request command specified in ISO 14443A (0x26)
if (!transmit_bits(abtReqa,7))
{
printf("Error: No tag available\n");
nfc_disconnect(pdi);
return 1;
}
// Anti-collision
transmit_bytes(abtSelectAll,2);
// Save the UID
memcpy(abtUid,abtRx,4);
memcpy(abtSelectTag+2,abtRx,5);
append_iso14443a_crc(abtSelectTag,7);
transmit_bytes(abtSelectTag,9);
// Test if we are dealing with a 4 bytes uid
if (abtUid[0]!= 0x88)
{
szUidLen = 4;
} else {
// We have to do the anti-collision for cascade level 2
abtSelectAll[0] = 0x95;
abtSelectTag[0] = 0x95;
// Anti-collision
transmit_bytes(abtSelectAll,2);
// Save the UID
memcpy(abtUid+4,abtRx,4);
memcpy(abtSelectTag+2,abtRx,5);
append_iso14443a_crc(abtSelectTag,7);
transmit_bytes(abtSelectTag,9);
szUidLen = 7;
}
// Request ATS, this only applies to tags that support ISO 14443A-4
if (abtRx[0] & SAK_FLAG_ATS_SUPPORTED) transmit_bytes(abtRats,4);
// Done, halt the tag now
transmit_bytes(abtHalt,4);
printf("\nFound tag with UID: ");
if (szUidLen == 4)
{
printf("%08x\n",swap_endian32(abtUid));
} else {
printf("%014llx\n",swap_endian64(abtUid)&0x00ffffffffffffffull);
}
nfc_disconnect(pdi);
return 0;
}

View file

@ -0,0 +1,37 @@
.TH NFC-EMULATE 1 "June 26, 2009"
.SH NAME
nfc-emulate \- NFC target emulation command line tool based on libnfc
.SH SYNOPSIS
.B nfc-emulate
.RI [ UID ]
.SH DESCRIPTION
.B nfc-emulate
is an tag emulatation tool. Tag emulation is one of the main added features in NFC.
To avoid abuse of existing systems, manufacturers of the NFC controller intentionally did not
support emulation of custom UID numbers.
The emulate tool demonstrates that this can still be done using transmission of raw-frames,
and the desired UID can be optionally specified.
Fast communication is necessary to respond in time during the anti-collision protocol.
Using the USB interface gives some timing issues but an embedded microprocessor could
be fast enough to emulate a tag with any UID. This makes it a serious thread
for security systems that rely only on the uniqueness of the UID.
.SH OPTIONS
.IR UID
8 hex digits format that represents desired UID (default is DEADBEAF).
.SH BUGS
Please report any bugs on the
.B libnfc
forum at
.BR http://www.libnfc.org/community/ "."
.SH LICENCE
.B libnfc
and
.B nfc-tools
are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS
Roel Verdult <roel@libnfc.org>
.PP
This manual page was written by Romuald Conty <romuald.conty@free.fr>.
It is licensed under the terms of the GNU GPL (version 2 or later).

160
src/examples/nfc-emulate.c Normal file
View file

@ -0,0 +1,160 @@
/*
Public platform independent Near Field Communication (NFC) library
Copyright (C) 2009, Roel Verdult
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "libnfc.h"
#include "messages.h"
static byte_t abtRecv[MAX_FRAME_LEN];
static size_t szRecvBits;
static dev_info* pdi;
// ISO14443A Anti-Collision response
byte_t abtAtqa [2] = { 0x04,0x00 };
byte_t abtUidBcc [5] = { 0xDE,0xAD,0xBE,0xAF,0x62 };
byte_t abtSak [9] = { 0x08,0xb6,0xdd };
void print_usage(char* argv[])
{
printf("Usage: %s [OPTIONS] [UID]\n", argv[0]);
printf("Options:\n");
printf("\t-h\tHelp. Print this message.\n");
printf("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
printf("\n");
printf("\t[UID]\tUID to emulate, specified as 8 HEX digits (default is DEADBEAF).\n");
}
int main(int argc, char *argv[])
{
byte_t* pbtTx = NULL;
size_t szTxBits;
bool quiet_output = false;
int arg, i;
// Get commandline options
for (arg=1;arg<argc;arg++) {
if (0 == strcmp(argv[arg], "-h")) {
print_usage(argv);
return 0;
} else if (0 == strcmp(argv[arg], "-q")) {
INFO("Quiet mode.");
quiet_output = true;
} else if((arg == argc-1) && (strlen(argv[arg]) == 8)) { // See if UID was specified as HEX string
byte_t abtTmp[3] = { 0x00,0x00,0x00 };
printf("[+] Using UID: %s\n",argv[arg]);
abtUidBcc[4]= 0x00;
for(i= 0; i < 4; ++i)
{
memcpy(abtTmp,argv[arg]+i*2,2);
abtUidBcc[i]= (byte_t) strtol((char*)abtTmp,NULL,16);
abtUidBcc[4] ^= abtUidBcc[i];
}
} else {
ERR("%s is not supported option.", argv[arg]);
print_usage(argv);
return -1;
}
}
// Try to open the NFC reader
pdi = nfc_connect(NULL);
if (pdi == INVALID_DEVICE_INFO)
{
printf("Error connecting NFC reader\n");
return 1;
}
printf("\n");
printf("[+] Connected to NFC reader: %s\n",pdi->acName);
printf("[+] Try to break out the auto-emulation, this requires a second reader!\n");
printf("[+] To do this, please send any command after the anti-collision\n");
printf("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
if (!nfc_target_init(pdi,abtRecv,&szRecvBits))
{
printf("Error: Could not come out of auto-emulation, no command was received\n");
return 1;
}
printf("[+] Received initiator command: ");
print_hex_bits(abtRecv,szRecvBits);
printf("[+] Configuring communication\n");
nfc_configure(pdi,DCO_HANDLE_CRC,false);
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
printf("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n",abtUidBcc[0],abtUidBcc[1],abtUidBcc[2],abtUidBcc[3]);
while(true)
{
// Test if we received a frame
if (nfc_target_receive_bits(pdi,abtRecv,&szRecvBits,NULL))
{
// Prepare the command to send back for the anti-collision request
switch(szRecvBits)
{
case 7: // Request or Wakeup
pbtTx = abtAtqa;
szTxBits = 16;
// New anti-collsion session started
if (!quiet_output) printf("\n");
break;
case 16: // Select All
pbtTx = abtUidBcc;
szTxBits = 40;
break;
case 72: // Select Tag
pbtTx = abtSak;
szTxBits = 24;
break;
default: // unknown length?
szTxBits = 0;
break;
}
if(!quiet_output)
{
printf("R: ");
print_hex_bits(abtRecv,szRecvBits);
}
// Test if we know how to respond
if(szTxBits)
{
// Send and print the command to the screen
nfc_target_send_bits(pdi,pbtTx,szTxBits,NULL);
if(!quiet_output)
{
printf("T: ");
print_hex_bits(pbtTx,szTxBits);
}
}
}
}
nfc_disconnect(pdi);
}

27
src/examples/nfc-list.1 Normal file
View file

@ -0,0 +1,27 @@
.TH NFC-LIST 1 "June 26, 2009"
.SH NAME
nfc-list \- List NFC targets command line tool based on libnfc
.SH SYNOPSIS
.B nfc-list
.SH DESCRIPTION
.B nfc-list
utility attempts to select available tags in the field. The NFC
controller is used to perform the selection procedure. This is different for each modulation type.
It tries to find a ISO/IEC 14443 type A, type B, Felica or Jewel Topaz tags.
This tool demonstrates that it is possible to setup a simple NFC system using less than 10 lines of code.
.SH BUGS
Please report any bugs on the
.B libnfc
forum at
.BR http://www.libnfc.org/community/ "."
.SH LICENCE
.B libnfc
and
.B nfc-tools
are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS
Roel Verdult <roel@libnfc.org>
.PP
This manual page was written by Romuald Conty <romuald.conty@free.fr>.
It is licensed under the terms of the GNU GPL (version 2 or later).

117
src/examples/nfc-list.c Normal file
View file

@ -0,0 +1,117 @@
/*
Public platform independent Near Field Communication (NFC) library
Copyright (C) 2009, Roel Verdult
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "libnfc.h"
#include "messages.h"
static dev_info* pdi;
static byte_t abtFelica[5] = { 0x00, 0xff, 0xff, 0x00, 0x00 };
int main(int argc, const char* argv[])
{
tag_info ti;
// Try to open the NFC device
pdi = nfc_connect(NULL);
// If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0
/*
nfc_device_desc_t ndd;
ndd.pcDriver = "ARYGON";
ndd.pcPort = "/dev/ttyUSB0";
ndd.uiSpeed = 115200;
pdi = nfc_connect(&ndd);
*/
if (pdi == INVALID_DEVICE_INFO)
{
ERR("Unable to connect to NFC device.");
return 1;
}
nfc_initiator_init(pdi);
// Drop the field for a while
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
// Let the reader only try once to find a tag
nfc_configure(pdi,DCO_INFINITE_SELECT,false);
// Configure the CRC and Parity settings
nfc_configure(pdi,DCO_HANDLE_CRC,true);
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
// Enable field so more power consuming cards can power themselves up
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
printf("Connected to NFC reader: %s\n\n",pdi->acName);
// Poll for a ISO14443A (MIFARE) tag
if (nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
{
printf("The following (NFC) ISO14443A tag was found:\n\n");
printf(" ATQA (SENS_RES): "); print_hex(ti.tia.abtAtqa,2);
printf(" UID (NFCID%c): ",(ti.tia.abtUid[0]==0x08?'3':'1')); print_hex(ti.tia.abtUid,ti.tia.szUidLen);
printf(" SAK (SEL_RES): "); print_hex(&ti.tia.btSak,1);
if (ti.tia.szAtsLen)
{
printf(" ATS (ATR): ");
print_hex(ti.tia.abtAts,ti.tia.szAtsLen);
}
}
// Poll for a Felica tag
if (nfc_initiator_select_tag(pdi,IM_FELICA_212,abtFelica,5,&ti) || nfc_initiator_select_tag(pdi,IM_FELICA_424,abtFelica,5,&ti))
{
printf("The following (NFC) Felica tag was found:\n\n");
printf("%18s","ID (NFCID2): "); print_hex(ti.tif.abtId,8);
printf("%18s","Parameter (PAD): "); print_hex(ti.tif.abtPad,8);
}
// Poll for a ISO14443B tag
if (nfc_initiator_select_tag(pdi,IM_ISO14443B_106,(byte_t*)"\x00",1,&ti))
{
printf("The following (NFC) ISO14443-B tag was found:\n\n");
printf(" ATQB: "); print_hex(ti.tib.abtAtqb,12);
printf(" ID: "); print_hex(ti.tib.abtId,4);
printf(" CID: %02x\n",ti.tib.btCid);
if (ti.tib.szInfLen>0)
{
printf(" INF: "); print_hex(ti.tib.abtInf,ti.tib.szInfLen);
}
printf("PARAMS: %02x %02x %02x %02x\n",ti.tib.btParam1,ti.tib.btParam2,ti.tib.btParam3,ti.tib.btParam4);
}
// Poll for a Jewel tag
if (nfc_initiator_select_tag(pdi,IM_JEWEL_106,NULL,0,&ti))
{
// No test results yet
printf("jewel\n");
}
nfc_disconnect(pdi);
return 1;
}

57
src/examples/nfc-mftool.1 Normal file
View file

@ -0,0 +1,57 @@
.TH NFC-MFTOOL 1 "June 26, 2009"
.SH NAME
nfc-mftool \- Mifare Classic command line tool based on libnfc
.SH SYNOPSIS
.B nfc-mftool
.RI \fR\fBr\fR|\fBw\fR
.RI \fR\fBa\fR|\fBb\fR
.IR KEYS
.IR DUMP
.SH DESCRIPTION
.B nfc-mftool
is an Mifare Classic tool that allow to read or write
.IR DUMP
file using Mifare keys provide in
.IR KEYS
file.
The Mifare Classic tag is one of the most widely used RFID tags.
The firmware in the NFC controller supports authenticating, reading and writing to/from Mifare Classic tags.
This tool demonstrate the speed of this library and its easy-of-use.
It possible to read and write the complete content of a Mifare Classic 4KB tag within 1 second.
It uses a binary Mifare Dump File to store the keys and date for all sectors.
.SH OPTIONS
.BR r " | " w
Perform read from (
.B r
) or write to (
.B w
)card.
.TP
.BR a " | " b
Use A or B Mifare keys.
.TP
.IR KEYS
Mifare dump that contain Mifare keys.
.TP
.IR DUMP
Used to write card to file ( r ) or file to card ( w )
.SH BUGS
Please report any bugs on the
.B libnfc
forum at
.BR http://www.libnfc.org/community/ "."
.SH LICENCE
.B libnfc
and
.B nfc-tools
are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS
Roel Verdult <roel@libnfc.org>
.PP
This manual page was written by Romuald Conty <romuald.conty@free.fr>.
It is licensed under the terms of the GNU GPL (version 2 or later).

423
src/examples/nfc-mftool.c Normal file
View file

@ -0,0 +1,423 @@
/*
Public platform independent Near Field Communication (NFC) library
Copyright (C) 2009, Roel Verdult
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include "libnfc.h"
#include "mifaretag.h"
static dev_info* pdi;
static tag_info ti;
static mifare_param mp;
static mifare_tag mtKeys;
static mifare_tag mtDump;
static bool bUseKeyA;
static bool bUseKeyFile;
static uint32_t uiBlocks;
static byte_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
};
static size_t num_keys = sizeof(keys) / 6;
bool is_first_block(uint32_t uiBlock)
{
// Test if we are in the small or big sectors
if (uiBlock < 128) return ((uiBlock)%4 == 0); else return ((uiBlock)%16 == 0);
}
bool is_trailer_block(uint32_t uiBlock)
{
// Test if we are in the small or big sectors
if (uiBlock < 128) return ((uiBlock+1)%4 == 0); else return ((uiBlock+1)%16 == 0);
}
uint32_t get_trailer_block(uint32_t uiFirstBlock)
{
// Test if we are in the small or big sectors
if (uiFirstBlock<128) return uiFirstBlock+3; else return uiFirstBlock+15;
}
bool authenticate(uint32_t uiBlock)
{
mifare_cmd mc;
uint32_t uiTrailerBlock;
size_t key_index;
// Key file authentication.
if (bUseKeyFile)
{
// Set the authentication information (uid)
memcpy(mp.mpa.abtUid,ti.tia.abtUid,4);
// Locate the trailer (with the keys) used for this sector
uiTrailerBlock = get_trailer_block(uiBlock);
// Determin if we should use the a or the b key
if (bUseKeyA)
{
mc = MC_AUTH_A;
memcpy(mp.mpa.abtKey,mtKeys.amb[uiTrailerBlock].mbt.abtKeyA,6);
} else {
mc = MC_AUTH_B;
memcpy(mp.mpa.abtKey,mtKeys.amb[uiTrailerBlock].mbt.abtKeyB,6);
}
// Try to authenticate for the current sector
if (nfc_initiator_mifare_cmd(pdi,mc,uiBlock,&mp))
return true;
}
// Auto authentication.
else
{
// Determin if we should use the a or the b key
mc = (bUseKeyA) ? MC_AUTH_A : MC_AUTH_B;
// Set the authentication information (uid)
memcpy(mp.mpa.abtUid,ti.tia.abtUid,4);
for (key_index = 0; key_index < num_keys; key_index++)
{
memcpy(mp.mpa.abtKey, keys + (key_index*6), 6);
if (nfc_initiator_mifare_cmd(pdi, mc, uiBlock, &mp))
{
/**
* @note: what about the other key?
*/
if (bUseKeyA)
memcpy(mtKeys.amb[uiBlock].mbt.abtKeyA,&mp.mpa.abtKey,6);
else
memcpy(mtKeys.amb[uiBlock].mbt.abtKeyB,&mp.mpa.abtKey,6);
return true;
}
nfc_initiator_select_tag(pdi, IM_ISO14443A_106, mp.mpa.abtUid, 4, NULL);
}
}
return false;
}
bool read_card()
{
int32_t iBlock;
bool bFailure = false;
printf("Reading out %d blocks |",uiBlocks+1);
// Read the card from end to begin
for (iBlock=uiBlocks; iBlock>=0; iBlock--)
{
// Authenticate everytime we reach a trailer block
if (is_trailer_block(iBlock))
{
// Show if the readout went well
if (bFailure)
{
printf("x");
// When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
{
printf("!\nError: tag was removed\n");
return 1;
}
bFailure = false;
} else {
// Skip this the first time, bFailure it means nothing (yet)
if (iBlock != uiBlocks)
{
printf(".");
}
}
fflush(stdout);
// Try to authenticate for the current sector
if (!authenticate(iBlock))
{
printf("!\nError: authentication failed for block %02x\n",iBlock);
return false;
}
// Try to read out the trailer
if (nfc_initiator_mifare_cmd(pdi,MC_READ,iBlock,&mp))
{
// Copy the keys over from our key dump and store the retrieved access bits
memcpy(mtDump.amb[iBlock].mbt.abtKeyA,mtKeys.amb[iBlock].mbt.abtKeyA,6);
memcpy(mtDump.amb[iBlock].mbt.abtAccessBits,mp.mpd.abtData+6,4);
memcpy(mtDump.amb[iBlock].mbt.abtKeyB,mtKeys.amb[iBlock].mbt.abtKeyB,6);
}
} else {
// Make sure a earlier readout did not fail
if (!bFailure)
{
// Try to read out the data block
if (nfc_initiator_mifare_cmd(pdi,MC_READ,iBlock,&mp))
{
memcpy(mtDump.amb[iBlock].mbd.abtData,mp.mpd.abtData,16);
} else {
bFailure = true;
}
}
}
}
printf("%c|\n",(bFailure)?'x':'.');
fflush(stdout);
return true;
}
bool write_card()
{
uint32_t uiBlock;
bool bFailure = false;
printf("Writing %d blocks |",uiBlocks+1);
// Write the card from begin to end;
for (uiBlock=0; uiBlock<=uiBlocks; uiBlock++)
{
// Authenticate everytime we reach the first sector of a new block
if (is_first_block(uiBlock))
{
// Show if the readout went well
if (bFailure)
{
printf("x");
// When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
{
printf("!\nError: tag was removed\n");
return false;
}
bFailure = false;
} else {
// Skip this the first time, bFailure it means nothing (yet)
if (uiBlock != 0)
{
printf(".");
}
}
fflush(stdout);
// Try to authenticate for the current sector
if (!authenticate(uiBlock))
{
printf("!\nError: authentication failed for block %02x\n",uiBlock);
return false;
}
}
if (is_trailer_block(uiBlock))
{
// Copy the keys over from our key dump and store the retrieved access bits
memcpy(mp.mpd.abtData,mtDump.amb[uiBlock].mbt.abtKeyA,6);
memcpy(mp.mpd.abtData+6,mtDump.amb[uiBlock].mbt.abtAccessBits,4);
memcpy(mp.mpd.abtData+10,mtDump.amb[uiBlock].mbt.abtKeyB,6);
// Try to write the trailer
nfc_initiator_mifare_cmd(pdi,MC_WRITE,uiBlock,&mp);
} else {
// The first block 0x00 is read only, skip this
if (uiBlock == 0) continue;
// Make sure a earlier write did not fail
if (!bFailure)
{
// Try to write the data block
memcpy(mp.mpd.abtData,mtDump.amb[uiBlock].mbd.abtData,16);
if (!nfc_initiator_mifare_cmd(pdi,MC_WRITE,uiBlock,&mp)) bFailure = true;
}
}
}
printf("%c|\n",(bFailure)?'x':'.');
fflush(stdout);
return true;
}
int main(int argc, const char* argv[])
{
bool b4K;
bool bReadAction;
byte_t* pbtUID;
FILE* pfKeys = NULL;
FILE* pfDump = NULL;
if (argc < 4)
{
printf("\n");
printf("%s r|w a|b <dump.mfd> [<keys.mfd>]\n", argv[0]);
printf("\n");
printf("r|w - Perform read from (r) or write to (w) card\n");
printf("a|b - Use A or B keys for action\n");
printf("<dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
printf("<keys.mfd> - MiFare Dump (MFD) that contain the keys (optional)\n");
printf("\n");
return 1;
}
printf("\nChecking arguments and settings\n");
bReadAction = (tolower(*(argv[1])) == 'r');
bUseKeyA = (tolower(*(argv[2])) == 'a');
bUseKeyFile = (argc > 4);
if (bUseKeyFile)
{
pfKeys = fopen(argv[4],"rb");
if (pfKeys == NULL)
{
printf("Could not open file: %s\n",argv[3]);
return 1;
}
if (fread(&mtKeys,1,sizeof(mtKeys),pfKeys) != sizeof(mtKeys))
{
printf("Could not read from keys file: %s\n",argv[4]);
fclose(pfKeys);
return 1;
}
fclose(pfKeys);
}
if (bReadAction)
{
memset(&mtDump,0x00,sizeof(mtDump));
} else {
pfDump = fopen(argv[3],"rb");
if (pfDump == NULL)
{
printf("Could not open dump file: %s\n",argv[3]);
return 1;
}
if (fread(&mtDump,1,sizeof(mtDump),pfDump) != sizeof(mtDump))
{
printf("Could not read from dump file: %s\n",argv[3]);
fclose(pfDump);
return 1;
}
fclose(pfDump);
}
printf("Succesful opened MIFARE the required files\n");
// Try to open the NFC reader
pdi = nfc_connect(NULL);
if (pdi == INVALID_DEVICE_INFO)
{
printf("Error connecting NFC reader\n");
return 1;
}
nfc_initiator_init(pdi);
// Drop the field for a while
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
// Let the reader only try once to find a tag
nfc_configure(pdi,DCO_INFINITE_SELECT,false);
nfc_configure(pdi,DCO_HANDLE_CRC,true);
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
// Enable field so more power consuming cards can power themselves up
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
printf("Connected to NFC reader: %s\n",pdi->acName);
// Try to find a MIFARE Classic tag
if (!nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
{
printf("Error: no tag was found\n");
nfc_disconnect(pdi);
return 1;
}
// Test if we are dealing with a MIFARE compatible tag
if ((ti.tia.btSak & 0x08) == 0)
{
printf("Error: tag is not a MIFARE Classic card\n");
nfc_disconnect(pdi);
return 1;
}
if (bUseKeyFile)
{
// Get the info from the key dump
b4K = (mtKeys.amb[0].mbm.abtATQA[1] == 0x02);
pbtUID = mtKeys.amb[0].mbm.abtUID;
// Compare if key dump UID is the same as the current tag UID
if (memcmp(ti.tia.abtUid,pbtUID,4) != 0)
{
printf("Expected MIFARE Classic %cK card with uid: %08x\n",b4K?'4':'1',swap_endian32(pbtUID));
}
}
// Get the info from the current tag
pbtUID = ti.tia.abtUid;
b4K = (ti.tia.abtAtqa[1] == 0x02);
printf("Found MIFARE Classic %cK card with uid: %08x\n",b4K?'4':'1',swap_endian32(pbtUID));
uiBlocks = (b4K)?0xff:0x3f;
if (bReadAction)
{
if (read_card())
{
printf("Writing data to file: %s\n",argv[3]);
fflush(stdout);
pfDump = fopen(argv[3],"wb");
if (fwrite(&mtDump,1,sizeof(mtDump),pfDump) != sizeof(mtDump))
{
printf("Could not write to file: %s\n",argv[3]);
return 1;
}
fclose(pfDump);
printf("Done, all bytes dumped to file!\n");
}
} else {
if (write_card())
{
printf("Done, all data is written to the card!\n");
}
}
nfc_disconnect(pdi);
return 0;
}

219
src/examples/nfc-mfultool.c Normal file
View file

@ -0,0 +1,219 @@
/*
Public platform independent Near Field Communication (NFC) library
Copyright (C) 2009, Roel Verdult
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include "libnfc.h"
#include "mifareultag.h"
static dev_info* pdi;
static tag_info ti;
static mifare_param mp;
static mifareul_tag mtDump;
bool read_card()
{
int page;
bool bSuccess = true;
// these are pages of 4 bytes each; we can read 4 pages at once.
for (page = 0; page <= 0xF; page += 4){
// Try to read out the data block
if (nfc_initiator_mifare_cmd(pdi,MC_READ,page,&mp))
{
memcpy(mtDump.amb[page / 4].mbd.abtData, mp.mpd.abtData, 16);
} else {
bSuccess = false;
break;
}
}
return bSuccess;
}
bool write_card()
{
uint32_t uiBlock = 0;
int page;
bool bFailure = false;
for (page = 0x4; page <= 0xF; page++) {
// Show if the readout went well
if (bFailure)
{
printf("x");
// When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
{
printf("!\nError: tag was removed\n");
return false;
}
bFailure = false;
} else {
// Skip this the first time, bFailure it means nothing (yet)
if (uiBlock != 0)
{
printf(".");
}
}
fflush(stdout);
// Make sure a earlier write did not fail
if (!bFailure)
{
// For the Mifare Ultralight, this write command can be used
// in compatibility mode, which only actually writes the first
// page (4 bytes). The Ultralight-specific Write command only
// writes one page at a time.
uiBlock = page / 4;
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData + ((page % 4) * 4), 16);
if (!nfc_initiator_mifare_cmd(pdi, MC_WRITE, page, &mp)) bFailure = true;
}
}
printf("%c|\n",(bFailure)?'x':'.');
fflush(stdout);
return true;
}
int main(int argc, const char* argv[])
{
bool bReadAction;
byte_t* pbtUID;
FILE* pfDump;
if (argc < 3)
{
printf("\n");
printf("%s r|w <dump.mfd>\n", argv[0]);
printf("\n");
printf("r|w - Perform read from or write to card\n");
printf("<dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
printf("\n");
return 1;
}
printf("\nChecking arguments and settings\n");
bReadAction = (tolower(*(argv[1])) == 'r');
if (bReadAction)
{
memset(&mtDump,0x00,sizeof(mtDump));
} else {
pfDump = fopen(argv[2],"rb");
if (pfDump == NULL)
{
printf("Could not open dump file: %s\n",argv[2]);
return 1;
}
if (fread(&mtDump,1,sizeof(mtDump),pfDump) != sizeof(mtDump))
{
printf("Could not read from dump file: %s\n",argv[2]);
fclose(pfDump);
return 1;
}
fclose(pfDump);
}
printf("Succesful opened the dump file\n");
// Try to open the NFC reader
pdi = nfc_connect(NULL);
if (pdi == INVALID_DEVICE_INFO)
{
printf("Error connecting NFC reader\n");
return 1;
}
nfc_initiator_init(pdi);
// Drop the field for a while
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
// Let the reader only try once to find a tag
nfc_configure(pdi,DCO_INFINITE_SELECT,false);
nfc_configure(pdi,DCO_HANDLE_CRC,true);
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
// Enable field so more power consuming cards can power themselves up
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
printf("Connected to NFC reader: %s\n",pdi->acName);
// Try to find a MIFARE Ultralight tag
if (!nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
{
printf("Error: no tag was found\n");
nfc_disconnect(pdi);
return 1;
}
// Test if we are dealing with a MIFARE compatible tag
if (ti.tia.abtAtqa[1] != 0x44){
printf("Error: tag is not a MIFARE Ultralight card\n");
nfc_disconnect(pdi);
return 1;
}
// Get the info from the current tag
pbtUID = ti.tia.abtUid;
printf("Found MIFARE Ultralight card with uid: %08x\n", swap_endian32(pbtUID));
if (bReadAction)
{
if (read_card())
{
printf("Writing data to file: %s\n",argv[2]);
fflush(stdout);
pfDump = fopen(argv[2],"wb");
if (pfDump == NULL)
{
printf("Could not open file: %s\n",argv[2]);
return 1;
}
if (fwrite(&mtDump,1,sizeof(mtDump),pfDump) != sizeof(mtDump))
{
printf("Could not write to file: %s\n",argv[2]);
return 1;
}
fclose(pfDump);
printf("Done, all bytes dumped to file!\n");
}
} else {
if (write_card())
{
printf("Done, all data is written to the card!\n");
}
}
nfc_disconnect(pdi);
return 0;
}

28
src/examples/nfc-relay.1 Normal file
View file

@ -0,0 +1,28 @@
.TH NFC-RELAY 1 "June 26, 2009"
.SH NAME
nfc-relay \- Relay attack command line tool based on libnfc
.SH SYNOPSIS
.B nfc-relay
.SH DESCRIPTION
.B nfc-relay
is an utility that demonstrates an relay attack. For this it requires two
NFC devices. One will emulate an ISO/IEC 14443 type A tag, while the 2nd
device will act as a reader. The genuine tag can be placed on the 2nd reader and
the tag emulator can be placed close to the original reader. All communication
is now relayed and shown in the screen on real-time.
.SH BUGS
Please report any bugs on the
.B libnfc
forum at
.BR http://www.libnfc.org/community/ "."
.SH LICENCE
.B libnfc
and
.B nfc-tools
are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS
Roel Verdult <roel@libnfc.org>
.PP
This manual page was written by Romuald Conty <romuald.conty@free.fr>.
It is licensed under the terms of the GNU GPL (version 2 or later).

134
src/examples/nfc-relay.c Normal file
View file

@ -0,0 +1,134 @@
/*
Public platform independent Near Field Communication (NFC) library
Copyright (C) 2009, Roel Verdult
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "libnfc.h"
#include "messages.h"
static byte_t abtReaderRx[MAX_FRAME_LEN];
static byte_t abtReaderRxPar[MAX_FRAME_LEN];
static size_t szReaderRxBits;
static byte_t abtTagRx[MAX_FRAME_LEN];
static byte_t abtTagRxPar[MAX_FRAME_LEN];
static size_t szTagRxBits;
static dev_info* pdiReader;
static dev_info* pdiTag;
void print_usage(char* argv[])
{
printf("Usage: %s [OPTIONS]\n", argv[0]);
printf("Options:\n");
printf("\t-h\tHelp. Print this message.\n");
printf("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
}
int main(int argc,char* argv[])
{
int arg;
bool quiet_output = false;
// Get commandline options
for (arg=1;arg<argc;arg++) {
if (0 == strcmp(argv[arg], "-h")) {
print_usage(argv);
return 0;
} else if (0 == strcmp(argv[arg], "-q")) {
INFO("Quiet mode.");
quiet_output = true;
} else {
ERR("%s is not supported option.", argv[arg]);
print_usage(argv);
return -1;
}
}
// Try to open the NFC emulator device
pdiTag = nfc_connect(NULL);
if (pdiTag == INVALID_DEVICE_INFO)
{
printf("Error connecting NFC emulator device\n");
return 1;
}
printf("\n");
printf("[+] Connected to the NFC emulator device\n");
printf("[+] Try to break out the auto-emulation, this requires a second reader!\n");
printf("[+] To do this, please send any command after the anti-collision\n");
printf("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
nfc_target_init(pdiTag,abtReaderRx,&szReaderRxBits);
printf("[+] Configuring emulator settings\n");
nfc_configure(pdiTag,DCO_HANDLE_CRC,false);
nfc_configure(pdiTag,DCO_HANDLE_PARITY,false);
nfc_configure(pdiTag,DCO_ACCEPT_INVALID_FRAMES,true);
printf("[+] Thank you, the emulated tag is initialized\n");
// Try to open the NFC reader
pdiReader = INVALID_DEVICE_INFO;
while (pdiReader == INVALID_DEVICE_INFO) pdiReader = nfc_connect(NULL);
printf("[+] Configuring NFC reader settings\n");
nfc_configure(pdiReader,DCO_HANDLE_CRC,false);
nfc_configure(pdiReader,DCO_HANDLE_PARITY,false);
nfc_configure(pdiReader,DCO_ACCEPT_INVALID_FRAMES,true);
printf("[+] Done, relaying frames now!\n\n");
while(true)
{
// Test if we received a frame from the reader
if (nfc_target_receive_bits(pdiTag,abtReaderRx,&szReaderRxBits,abtReaderRxPar))
{
// Drop down the field before sending a REQA command and start a new session
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26)
{
// Drop down field for a very short time (original tag will reboot)
nfc_configure(pdiReader,DCO_ACTIVATE_FIELD,false);
if(!quiet_output)
printf("\n");
nfc_configure(pdiReader,DCO_ACTIVATE_FIELD,true);
}
// Print the reader frame to the screen
if(!quiet_output)
{
printf("R: ");
print_hex_par(abtReaderRx,szReaderRxBits,abtReaderRxPar);
}
// Forward the frame to the original tag
if (nfc_initiator_transceive_bits(pdiReader,abtReaderRx,szReaderRxBits,abtReaderRxPar,abtTagRx,&szTagRxBits,abtTagRxPar))
{
// Redirect the answer back to the reader
nfc_target_send_bits(pdiTag,abtTagRx,szTagRxBits,abtTagRxPar);
// Print the tag frame to the screen
if(!quiet_output)
{
printf("T: ");
print_hex_par(abtTagRx,szTagRxBits,abtTagRxPar);
}
}
}
}
nfc_disconnect(pdiTag);
nfc_disconnect(pdiReader);
}

View file

@ -0,0 +1,37 @@
#include <stdio.h>
#include <string.h>
#include "libnfc.h"
int main(int argc, const char *argv[])
{
dev_info *pdi;
tag_info ti;
byte_t abtRecv[MAX_FRAME_LEN];
size_t szRecvBits;
byte_t send[] = "Hello World!";
pdi = nfc_connect(NULL);
if (!pdi || !nfc_initiator_init(pdi)
|| !nfc_initiator_select_dep_target(pdi, IM_PASSIVE_DEP, NULL, 0,
NULL, 0, NULL, 0, &ti)) {
printf
("unable to connect, initialize, or select the target\n");
return 1;
}
printf("Sending : %s\n", send);
if (!nfc_initiator_transceive_dep_bytes(pdi,
send,
strlen((char*)send), abtRecv,
&szRecvBits)) {
printf("unable to send data\n");
return 1;
}
abtRecv[szRecvBits] = 0;
printf("Received: %s\n", abtRecv);
nfc_initiator_deselect_tag(pdi);
nfc_disconnect(pdi);
return 0;
}

View file

@ -0,0 +1,31 @@
#include <stdio.h>
#include "libnfc.h"
int main(int argc, const char *argv[])
{
byte_t abtRecv[MAX_FRAME_LEN];
size_t szRecvBits;
byte_t send[] = "Hello Mars!";
dev_info *pdi = nfc_connect(NULL);
if (!pdi || !nfc_target_init(pdi, abtRecv, &szRecvBits)) {
printf("unable to connect or initialize\n");
return 1;
}
if (!nfc_target_receive_dep_bytes(pdi, abtRecv, &szRecvBits)) {
printf("unable to receive data\n");
return 1;
}
abtRecv[szRecvBits] = 0;
printf("Received: %s\n", abtRecv);
printf("Sending : %s\n", send);
if (!nfc_target_send_dep_bytes(pdi, send, 11)) {
printf("unable to send data\n");
return 1;
}
nfc_disconnect(pdi);
return 0;
}