libnfc 1.8.0
nfc-emulate-forum-tag2.c
Go to the documentation of this file.
1/*-
2 * Free/Libre Near Field Communication (NFC) library
3 *
4 * Libnfc historical contributors:
5 * Copyright (C) 2009 Roel Verdult
6 * Copyright (C) 2009-2013 Romuald Conty
7 * Copyright (C) 2010-2012 Romain Tartière
8 * Copyright (C) 2010-2013 Philippe Teuwen
9 * Copyright (C) 2012-2013 Ludovic Rousseau
10 * See AUTHORS file for a more comprehensive list of contributors.
11 * Additional contributors of this file:
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 * 1) Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2 )Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Note that this license only applies on the examples, NFC library itself is under LGPL
34 *
35 */
36
56/*
57 * This implementation was written based on information provided by the
58 * following documents:
59 *
60 * NFC Forum Type 2 Tag Operation
61 * Technical Specification
62 * NFCForum-TS-Type-2-Tag_1.0 - 2007-07-09
63 *
64 * ISO/IEC 14443-3
65 * First edition - 2001-02-01
66 * Identification cards — Contactless integrated circuit(s) cards — Proximity cards
67 * Part 3: Initialization and anticollision
68 */
69
70#ifdef HAVE_CONFIG_H
71# include "config.h"
72#endif // HAVE_CONFIG_H
73
74#include <errno.h>
75#include <signal.h>
76#include <stdlib.h>
77
78#include <nfc/nfc.h>
79#include <nfc/nfc-emulation.h>
80
81#include "utils/nfc-utils.h"
82
83static nfc_device *pnd;
84static nfc_context *context;
85
86static void
87stop_emulation(int sig)
88{
89 (void)sig;
90 if (pnd != NULL) {
92 } else {
93 nfc_exit(context);
94 exit(EXIT_FAILURE);
95 }
96}
97
98static uint8_t __nfcforum_tag2_memory_area[] = {
99 0x00, 0x00, 0x00, 0x00, // Block 0
100 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0xFF, 0xFF, // Block 2 (Static lock bytes: CC area and data area are read-only locked)
102 0xE1, 0x10, 0x06, 0x0F, // Block 3 (CC - NFC-Forum Tag Type 2 version 1.0, Data area (from block 4 to the end) is 48 bytes, Read-only mode)
103
104 0x03, 33, 0xd1, 0x02, // Block 4 (NDEF)
105 0x1c, 0x53, 0x70, 0x91,
106 0x01, 0x09, 0x54, 0x02,
107 0x65, 0x6e, 0x4c, 0x69,
108
109 0x62, 0x6e, 0x66, 0x63,
110 0x51, 0x01, 0x0b, 0x55,
111 0x03, 0x6c, 0x69, 0x62,
112 0x6e, 0x66, 0x63, 0x2e,
113
114 0x6f, 0x72, 0x67, 0x00,
115 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00,
118};
119
120#define READ 0x30
121#define WRITE 0xA2
122#define SECTOR_SELECT 0xC2
123
124#define HALT 0x50
125static int
126nfcforum_tag2_io(struct nfc_emulator *emulator, const uint8_t *data_in, const size_t data_in_len, uint8_t *data_out, const size_t data_out_len)
127{
128 int res = 0;
129
130 uint8_t *nfcforum_tag2_memory_area = (uint8_t *)(emulator->user_data);
131
132 printf(" In: ");
133 print_hex(data_in, data_in_len);
134
135 switch (data_in[0]) {
136 case READ:
137 if (data_out_len >= 16) {
138 memcpy(data_out, nfcforum_tag2_memory_area + (data_in[1] * 4), 16);
139 res = 16;
140 } else {
141 res = -ENOSPC;
142 }
143 break;
144 case HALT:
145 printf("HALT sent\n");
146 res = -ECONNABORTED;
147 break;
148 default:
149 printf("Unknown command: 0x%02x\n", data_in[0]);
150 res = -ENOTSUP;
151 }
152
153 if (res < 0) {
154 ERR("%s (%d)", strerror(-res), -res);
155 } else {
156 printf(" Out: ");
157 print_hex(data_out, res);
158 }
159
160 return res;
161}
162
163int
164main(int argc, char *argv[])
165{
166 (void)argc;
167 (void)argv;
168
169 nfc_target nt = {
170 .nm = {
171 .nmt = NMT_ISO14443A,
172 .nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init()
173 },
174 .nti = {
175 .nai = {
176 .abtAtqa = { 0x00, 0x04 },
177 .abtUid = { 0x08, 0x00, 0xb0, 0x0b },
178 .szUidLen = 4,
179 .btSak = 0x00,
180 .szAtsLen = 0,
181 },
182 }
183 };
184
185 struct nfc_emulation_state_machine state_machine = {
186 .io = nfcforum_tag2_io
187 };
188
189 struct nfc_emulator emulator = {
190 .target = &nt,
191 .state_machine = &state_machine,
192 .user_data = __nfcforum_tag2_memory_area,
193 };
194
195 signal(SIGINT, stop_emulation);
196
197 nfc_init(&context);
198 if (context == NULL) {
199 ERR("Unable to init libnfc (malloc)");
200 exit(EXIT_FAILURE);
201 }
202 pnd = nfc_open(context, NULL);
203
204 if (pnd == NULL) {
205 ERR("Unable to open NFC device");
206 nfc_exit(context);
207 exit(EXIT_FAILURE);
208 }
209
210 printf("NFC device: %s opened\n", nfc_device_get_name(pnd));
211 printf("Emulating NDEF tag now, please touch it with a second NFC device\n");
212
213 if (nfc_emulate_target(pnd, &emulator, 0) < 0) {
214 nfc_perror(pnd, argv[0]);
215 nfc_close(pnd);
216 nfc_exit(context);
217 exit(EXIT_FAILURE);
218 }
219
220 nfc_close(pnd);
221 nfc_exit(context);
222 exit(EXIT_SUCCESS);
223}
const char * nfc_device_get_name(nfc_device *pnd)
Returns the device name.
Definition: nfc.c:1209
void nfc_close(nfc_device *pnd)
Close from a NFC device.
Definition: nfc.c:339
nfc_device * nfc_open(nfc_context *context, const nfc_connstring connstring)
Open a NFC device.
Definition: nfc.c:277
int nfc_abort_command(nfc_device *pnd)
Abort current running command.
Definition: nfc.c:1036
void nfc_perror(const nfc_device *pnd, const char *pcString)
Display the last error occured on a nfc_device.
Definition: nfc.c:1183
void nfc_exit(nfc_context *context)
Deinitialize libnfc. Should be called after closing all open devices and before your application term...
Definition: nfc.c:248
void nfc_init(nfc_context **context)
Initialize libnfc. This function must be called before calling any other libnfc function.
Definition: nfc.c:231
int nfc_emulate_target(nfc_device *pnd, struct nfc_emulator *emulator, const int timeout)
Emulate a target.
Definition: nfc-emulation.c:48
Provide a small API to ease emulation in libnfc.
Provide some examples shared functions like print, parity calculation, options parsing.
#define ERR(...)
Print a error message.
Definition: nfc-utils.h:85
libnfc interface
NFC library context Struct which contains internal options, references, pointers, etc....
Definition: nfc-internal.h:175
NFC device information.
Definition: nfc-internal.h:190
NFC emulation state machine structure.
Definition: nfc-emulation.h:59
NFC emulator structure.
Definition: nfc-emulation.h:49
NFC target structure.
Definition: nfc-types.h:351