2010-09-28 18:15:59 +02:00
|
|
|
/*-
|
|
|
|
* Public platform independent Near Field Communication (NFC) library
|
|
|
|
*
|
2010-09-29 17:26:17 +02:00
|
|
|
* Copyright (C) 2010, Roel Verdult
|
2010-09-28 18:15:59 +02:00
|
|
|
*
|
|
|
|
* 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/>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2010-10-08 17:37:21 +02:00
|
|
|
* @file nfc-emulate-forum-tag4.c
|
2010-10-14 13:53:27 +02:00
|
|
|
* @brief Emulates a NFC Forum Tag Type 4 with a NDEF message
|
2010-09-28 18:15:59 +02:00
|
|
|
*/
|
|
|
|
|
2010-10-06 23:04:52 +02:00
|
|
|
// Notes & differences with nfc-emulate-tag:
|
|
|
|
// - This example only works with PN532 because it relies on
|
|
|
|
// its internal handling of ISO14443-4 specificities.
|
|
|
|
// - Thanks to this internal handling & injection of WTX frames,
|
|
|
|
// this example works on readers very strict on timing
|
|
|
|
// - This example expects a hardcoded list of commands and
|
|
|
|
// more precisely the commands sent by a Nokia NFC when
|
|
|
|
// discovering a NFC-Forum tag type4:
|
|
|
|
// * Anticoll & RATS
|
|
|
|
// * App Select by name "e103e103e103"
|
|
|
|
// * App Select by name "e103e103e103"
|
|
|
|
// * App Select by name "D2760000850100"
|
|
|
|
// * Select CC
|
|
|
|
// * ReadBinary CC
|
|
|
|
// * Select NDEF
|
|
|
|
// * Read first 2 NDEF bytes
|
|
|
|
// * Read remaining of NDEF file
|
|
|
|
|
2010-09-28 18:15:59 +02:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif // HAVE_CONFIG_H
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <nfc/nfc.h>
|
|
|
|
|
|
|
|
#include <nfc/nfc-messages.h>
|
|
|
|
#include "nfc-utils.h"
|
|
|
|
|
|
|
|
#define MAX_FRAME_LEN 264
|
|
|
|
|
|
|
|
static byte_t abtRx[MAX_FRAME_LEN];
|
2010-10-12 16:56:42 +02:00
|
|
|
static size_t szRx;
|
2010-09-28 18:15:59 +02:00
|
|
|
static nfc_device_t *pnd;
|
|
|
|
static bool quiet_output = false;
|
|
|
|
|
|
|
|
#define SYMBOL_PARAM_fISO14443_4_PICC 0x20
|
|
|
|
|
2010-10-12 16:56:42 +02:00
|
|
|
bool send_bytes (const byte_t * pbtTx, const size_t szTx)
|
2010-09-28 18:15:59 +02:00
|
|
|
{
|
|
|
|
// Show transmitted command
|
|
|
|
if (!quiet_output) {
|
2010-09-30 18:02:02 +02:00
|
|
|
printf ("Sent data: ");
|
2010-10-12 16:56:42 +02:00
|
|
|
print_hex (pbtTx, szTx);
|
2010-09-28 18:15:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Transmit the command bytes
|
2010-10-12 16:56:42 +02:00
|
|
|
if (!nfc_target_send_bytes(pnd, pbtTx, szTx)) {
|
2010-09-29 17:26:17 +02:00
|
|
|
nfc_perror (pnd, "nfc_target_send_bytes");
|
2010-10-05 12:05:22 +02:00
|
|
|
exit(EXIT_FAILURE);
|
2010-09-29 17:26:17 +02:00
|
|
|
}
|
2010-10-05 12:05:22 +02:00
|
|
|
// Succesful transfer
|
|
|
|
return true;
|
|
|
|
}
|
2010-09-28 18:15:59 +02:00
|
|
|
|
2010-10-05 12:05:22 +02:00
|
|
|
bool receive_bytes (void)
|
|
|
|
{
|
2010-10-12 16:56:42 +02:00
|
|
|
if (!nfc_target_receive_bytes(pnd,abtRx,&szRx)) {
|
2010-10-04 15:28:36 +02:00
|
|
|
nfc_perror (pnd, "nfc_target_receive_bytes");
|
2010-10-05 12:05:22 +02:00
|
|
|
exit(EXIT_FAILURE);
|
2010-09-29 17:26:17 +02:00
|
|
|
}
|
2010-09-28 18:15:59 +02:00
|
|
|
|
|
|
|
// Show received answer
|
|
|
|
if (!quiet_output) {
|
2010-09-30 18:02:02 +02:00
|
|
|
printf ("Received data: ");
|
2010-10-12 16:56:42 +02:00
|
|
|
print_hex (abtRx, szRx);
|
2010-09-28 18:15:59 +02:00
|
|
|
}
|
|
|
|
// Succesful transfer
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main (int argc, char *argv[])
|
|
|
|
{
|
|
|
|
// Try to open the NFC reader
|
|
|
|
pnd = nfc_connect (NULL);
|
|
|
|
|
|
|
|
if (pnd == NULL) {
|
2010-09-29 17:26:17 +02:00
|
|
|
ERR("Unable to connect to NFC device");
|
|
|
|
return EXIT_FAILURE;
|
2010-09-28 18:15:59 +02:00
|
|
|
}
|
|
|
|
|
2010-10-04 20:12:57 +02:00
|
|
|
printf ("Connected to NFC device: %s\n", pnd->acName);
|
|
|
|
printf ("Emulating NDEF tag now, please touch it with a second NFC device\n");
|
2010-10-04 14:46:03 +02:00
|
|
|
|
|
|
|
nfc_target_t nt = {
|
2010-10-13 21:17:51 +02:00
|
|
|
.nm.nmt = NMT_ISO14443A,
|
2010-10-14 18:27:50 +02:00
|
|
|
.nm.nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init()
|
2010-10-04 14:46:03 +02:00
|
|
|
.nti.nai.abtAtqa = { 0x00, 0x04 },
|
|
|
|
.nti.nai.abtUid = { 0x08, 0x00, 0xb0, 0x0b },
|
|
|
|
.nti.nai.btSak = 0x20,
|
|
|
|
.nti.nai.szUidLen = 4,
|
|
|
|
.nti.nai.szAtsLen = 0,
|
|
|
|
};
|
|
|
|
|
2010-10-14 18:27:50 +02:00
|
|
|
if (!nfc_target_init (pnd, NTM_ISO14443_4_PICC_ONLY, &nt, abtRx, &szRx)) {
|
2010-09-29 17:26:17 +02:00
|
|
|
nfc_perror (pnd, "nfc_target_init");
|
|
|
|
ERR("Could not come out of auto-emulation, no command was received");
|
|
|
|
return EXIT_FAILURE;
|
2010-09-28 18:15:59 +02:00
|
|
|
}
|
|
|
|
|
2010-09-30 18:02:02 +02:00
|
|
|
if (!quiet_output) {
|
|
|
|
printf ("Received data: ");
|
2010-10-12 16:56:42 +02:00
|
|
|
print_hex (abtRx, szRx);
|
2010-09-30 18:02:02 +02:00
|
|
|
}
|
|
|
|
|
2010-10-04 23:01:11 +02:00
|
|
|
//Receiving data: e0 40
|
|
|
|
//= RATS, FSD=48
|
|
|
|
//Actually PN532 already sent back the ATS so nothing to send now
|
2010-10-05 12:05:22 +02:00
|
|
|
receive_bytes();
|
|
|
|
//Receiving data: 00 a4 04 00 06 e1 03 e1 03 e1 03
|
|
|
|
//= App Select by name "e103e103e103"
|
|
|
|
send_bytes((const byte_t*)"\x6a\x87",2);
|
|
|
|
receive_bytes();
|
|
|
|
//Receiving data: 00 a4 04 00 06 e1 03 e1 03 e1 03
|
2010-10-04 23:01:11 +02:00
|
|
|
//= App Select by name "e103e103e103"
|
2010-10-05 12:05:22 +02:00
|
|
|
send_bytes((const byte_t*)"\x6a\x87",2);
|
|
|
|
receive_bytes();
|
|
|
|
//Receiving data: 00 a4 04 00 07 d2 76 00 00 85 01 00
|
2010-10-04 23:01:11 +02:00
|
|
|
//= App Select by name "D2760000850100"
|
2010-10-05 12:05:22 +02:00
|
|
|
send_bytes((const byte_t*)"\x90\x00",2);
|
|
|
|
receive_bytes();
|
|
|
|
//Receiving data: 00 a4 00 00 02 e1 03
|
2010-10-04 23:01:11 +02:00
|
|
|
//= Select CC
|
2010-10-05 12:05:22 +02:00
|
|
|
send_bytes((const byte_t*)"\x90\x00",2);
|
|
|
|
receive_bytes();
|
|
|
|
//Receiving data: 00 b0 00 00 0f
|
2010-10-04 23:01:11 +02:00
|
|
|
//= ReadBinary CC
|
|
|
|
//We send CC + OK
|
2010-10-05 12:05:22 +02:00
|
|
|
send_bytes((const byte_t*)"\x00\x0f\x10\x00\x3b\x00\x34\x04\x06\xe1\x04\x0e\xe0\x00\x00\x90\x00",17);
|
|
|
|
receive_bytes();
|
|
|
|
//Receiving data: 00 a4 00 00 02 e1 04
|
2010-10-04 23:01:11 +02:00
|
|
|
//= Select NDEF
|
2010-10-05 12:05:22 +02:00
|
|
|
send_bytes((const byte_t*)"\x90\x00",2);
|
|
|
|
receive_bytes();
|
|
|
|
//Receiving data: 00 b0 00 00 02
|
2010-10-04 23:01:11 +02:00
|
|
|
//= Read first 2 NDEF bytes
|
|
|
|
//Sent NDEF Length=0x21
|
2010-10-05 12:05:22 +02:00
|
|
|
send_bytes((const byte_t*)"\x00\x21\x90\x00",4);
|
|
|
|
receive_bytes();
|
|
|
|
//Receiving data: 00 b0 00 02 21
|
|
|
|
//= Read remaining of NDEF file
|
|
|
|
send_bytes((const byte_t*)"\xd1\x02\x1c\x53\x70\x91\x01\x09\x54\x02\x65\x6e\x4c\x69\x62\x6e\x66\x63\x51\x01\x0b\x55\x03\x6c\x69\x62\x6e\x66\x63\x2e\x6f\x72\x67\x90\x00",35);
|
2010-09-28 18:15:59 +02:00
|
|
|
|
|
|
|
nfc_disconnect(pnd);
|
|
|
|
exit (EXIT_SUCCESS);
|
|
|
|
}
|