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 
83 static nfc_device *pnd;
84 static nfc_context *context;
85 
86 static void
87 stop_emulation(int sig)
88 {
89  (void)sig;
90  if (pnd != NULL) {
91  nfc_abort_command(pnd);
92  } else {
93  nfc_exit(context);
94  exit(EXIT_FAILURE);
95  }
96 }
97 
98 static 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
125 static int
126 nfcforum_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 
163 int
164 main(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