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