libnfc  1.4.2
nfc-emulate-forum-tag4.c
Go to the documentation of this file.
1 /*-
2  * Public platform independent Near Field Communication (NFC) library examples
3  *
4  * Copyright (C) 2010, Roel Verdult, Romuald Conty
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  * 1) Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2 )Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  *
26  * Note that this license only applies on the examples, NFC library itself is under LGPL
27  *
28  */
29 
35 // Notes & differences with nfc-emulate-tag:
36 // - This example only works with PN532 because it relies on
37 // its internal handling of ISO14443-4 specificities.
38 // - Thanks to this internal handling & injection of WTX frames,
39 // this example works on readers very strict on timing
40 // - This example expects a hardcoded list of commands and
41 // more precisely the commands sent by a Nokia NFC when
42 // discovering a NFC-Forum tag type4:
43 // * Anticoll & RATS
44 // * App Select by name "e103e103e103"
45 // * App Select by name "e103e103e103"
46 // * App Select by name "D2760000850100"
47 // * Select CC
48 // * ReadBinary CC
49 // * Select NDEF
50 // * Read first 2 NDEF bytes
51 // * Read remaining of NDEF file
52 
53 #ifdef HAVE_CONFIG_H
54 # include "config.h"
55 #endif // HAVE_CONFIG_H
56 
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <stddef.h>
60 #include <stdint.h>
61 #include <string.h>
62 
63 #include <nfc/nfc.h>
64 
65 #include <nfc/nfc-messages.h>
66 #include "nfc-utils.h"
67 
68 #define MAX_FRAME_LEN 264
69 
70 static byte_t abtRx[MAX_FRAME_LEN];
71 static size_t szRx;
72 static nfc_device_t *pnd;
73 static bool quiet_output = false;
74 
75 #define SYMBOL_PARAM_fISO14443_4_PICC 0x20
76 
77 bool send_bytes (const byte_t * pbtTx, const size_t szTx)
78 {
79  // Show transmitted command
80  if (!quiet_output) {
81  printf ("Sent data: ");
82  print_hex (pbtTx, szTx);
83  }
84 
85  // Transmit the command bytes
86  if (!nfc_target_send_bytes(pnd, pbtTx, szTx)) {
87  nfc_perror (pnd, "nfc_target_send_bytes");
88  exit(EXIT_FAILURE);
89  }
90  // Succesful transfer
91  return true;
92 }
93 
94 bool receive_bytes (void)
95 {
96  if (!nfc_target_receive_bytes(pnd,abtRx,&szRx)) {
97  nfc_perror (pnd, "nfc_target_receive_bytes");
98  exit(EXIT_FAILURE);
99  }
100 
101  // Show received answer
102  if (!quiet_output) {
103  printf ("Received data: ");
104  print_hex (abtRx, szRx);
105  }
106  // Succesful transfer
107  return true;
108 }
109 
110 int
111 main (int argc, char *argv[])
112 {
113  // Try to open the NFC reader
114  pnd = nfc_connect (NULL);
115 
116  if (pnd == NULL) {
117  ERR("Unable to connect to NFC device");
118  return EXIT_FAILURE;
119  }
120 
121  printf ("Connected to NFC device: %s\n", pnd->acName);
122  printf ("Emulating NDEF tag now, please touch it with a second NFC device\n");
123 
124  nfc_target_t nt = {
125  .nm.nmt = NMT_ISO14443A,
126  .nm.nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init()
127  .nti.nai.abtAtqa = { 0x00, 0x04 },
128  .nti.nai.abtUid = { 0x08, 0x00, 0xb0, 0x0b },
129  .nti.nai.btSak = 0x20,
130  .nti.nai.szUidLen = 4,
131  .nti.nai.szAtsLen = 0,
132  };
133 
134  if (!nfc_target_init (pnd, &nt, abtRx, &szRx)) {
135  nfc_perror (pnd, "nfc_target_init");
136  ERR("Could not come out of auto-emulation, no command was received");
137  return EXIT_FAILURE;
138  }
139 
140  if (!quiet_output) {
141  printf ("Received data: ");
142  print_hex (abtRx, szRx);
143  }
144 
145 //Receiving data: e0 40
146 //= RATS, FSD=48
147 //Actually PN532 already sent back the ATS so nothing to send now
148  receive_bytes();
149 //Receiving data: 00 a4 04 00 06 e1 03 e1 03 e1 03
150 //= App Select by name "e103e103e103"
151  send_bytes((const byte_t*)"\x6a\x87",2);
152  receive_bytes();
153 //Receiving data: 00 a4 04 00 06 e1 03 e1 03 e1 03
154 //= App Select by name "e103e103e103"
155  send_bytes((const byte_t*)"\x6a\x87",2);
156  receive_bytes();
157 //Receiving data: 00 a4 04 00 07 d2 76 00 00 85 01 00
158 //= App Select by name "D2760000850100"
159  send_bytes((const byte_t*)"\x90\x00",2);
160  receive_bytes();
161 //Receiving data: 00 a4 00 00 02 e1 03
162 //= Select CC
163  send_bytes((const byte_t*)"\x90\x00",2);
164  receive_bytes();
165 //Receiving data: 00 b0 00 00 0f
166 //= ReadBinary CC
167 //We send CC + OK
168  send_bytes((const byte_t*)"\x00\x0f\x10\x00\x3b\x00\x34\x04\x06\xe1\x04\x0e\xe0\x00\x00\x90\x00",17);
169  receive_bytes();
170 //Receiving data: 00 a4 00 00 02 e1 04
171 //= Select NDEF
172  send_bytes((const byte_t*)"\x90\x00",2);
173  receive_bytes();
174 //Receiving data: 00 b0 00 00 02
175 //= Read first 2 NDEF bytes
176 //Sent NDEF Length=0x21
177  send_bytes((const byte_t*)"\x00\x21\x90\x00",4);
178  receive_bytes();
179 //Receiving data: 00 b0 00 02 21
180 //= Read remaining of NDEF file
181  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);
182 
183  nfc_disconnect(pnd);
184  exit (EXIT_SUCCESS);
185 }