libnfc 1.4.2
nfc-emulate-forum-tag4.c
Go to the documentation of this file.
00001 /*-
00002  * Public platform independent Near Field Communication (NFC) library examples
00003  * 
00004  * Copyright (C) 2010, Roel Verdult, Romuald Conty
00005  * 
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *  1) Redistributions of source code must retain the above copyright notice,
00009  *  this list of conditions and the following disclaimer. 
00010  *  2 )Redistributions in binary form must reproduce the above copyright
00011  *  notice, this list of conditions and the following disclaimer in the
00012  *  documentation and/or other materials provided with the distribution.
00013  *
00014  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00015  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00016  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00017  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00018  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00019  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00020  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00021  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00022  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00023  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00024  * POSSIBILITY OF SUCH DAMAGE.
00025  * 
00026  * Note that this license only applies on the examples, NFC library itself is under LGPL
00027  *
00028  */
00029 
00035 // Notes & differences with nfc-emulate-tag:
00036 // - This example only works with PN532 because it relies on
00037 //   its internal handling of ISO14443-4 specificities.
00038 // - Thanks to this internal handling & injection of WTX frames,
00039 //   this example works on readers very strict on timing
00040 // - This example expects a hardcoded list of commands and
00041 //   more precisely the commands sent by a Nokia NFC when
00042 //   discovering a NFC-Forum tag type4:
00043 //   * Anticoll & RATS
00044 //   * App Select by name "e103e103e103"
00045 //   * App Select by name "e103e103e103"
00046 //   * App Select by name "D2760000850100"
00047 //   * Select CC
00048 //   * ReadBinary CC
00049 //   * Select NDEF
00050 //   * Read first 2 NDEF bytes
00051 //   * Read remaining of NDEF file
00052 
00053 #ifdef HAVE_CONFIG_H
00054 #  include "config.h"
00055 #endif // HAVE_CONFIG_H
00056 
00057 #include <stdio.h>
00058 #include <stdlib.h>
00059 #include <stddef.h>
00060 #include <stdint.h>
00061 #include <string.h>
00062 
00063 #include <nfc/nfc.h>
00064 
00065 #include <nfc/nfc-messages.h>
00066 #include "nfc-utils.h"
00067 
00068 #define MAX_FRAME_LEN 264
00069 
00070 static byte_t abtRx[MAX_FRAME_LEN];
00071 static size_t szRx;
00072 static nfc_device_t *pnd;
00073 static bool quiet_output = false;
00074 
00075 #define SYMBOL_PARAM_fISO14443_4_PICC   0x20
00076 
00077 bool send_bytes (const byte_t * pbtTx, const size_t szTx)
00078 {
00079   // Show transmitted command
00080   if (!quiet_output) {
00081     printf ("Sent data: ");
00082     print_hex (pbtTx, szTx);
00083   }
00084 
00085   // Transmit the command bytes
00086   if (!nfc_target_send_bytes(pnd, pbtTx, szTx)) {
00087     nfc_perror (pnd, "nfc_target_send_bytes");
00088     exit(EXIT_FAILURE);
00089   }
00090   // Succesful transfer
00091   return true;
00092 }
00093 
00094 bool receive_bytes (void)
00095 {
00096   if (!nfc_target_receive_bytes(pnd,abtRx,&szRx)) {
00097     nfc_perror (pnd, "nfc_target_receive_bytes");
00098     exit(EXIT_FAILURE);
00099   }
00100 
00101   // Show received answer
00102   if (!quiet_output) {
00103     printf ("Received data: ");
00104     print_hex (abtRx, szRx);
00105   }
00106   // Succesful transfer
00107   return true;
00108 }
00109 
00110 int
00111 main (int argc, char *argv[])
00112 {
00113   // Try to open the NFC reader
00114   pnd = nfc_connect (NULL);
00115 
00116   if (pnd == NULL) {
00117     ERR("Unable to connect to NFC device");
00118     return EXIT_FAILURE;
00119   }
00120 
00121   printf ("Connected to NFC device: %s\n", pnd->acName);
00122   printf ("Emulating NDEF tag now, please touch it with a second NFC device\n");
00123 
00124   nfc_target_t nt = {
00125     .nm.nmt = NMT_ISO14443A,
00126     .nm.nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init()
00127     .nti.nai.abtAtqa = { 0x00, 0x04 },
00128     .nti.nai.abtUid = { 0x08, 0x00, 0xb0, 0x0b },
00129     .nti.nai.btSak = 0x20,
00130     .nti.nai.szUidLen = 4,
00131     .nti.nai.szAtsLen = 0,
00132   };
00133 
00134   if (!nfc_target_init (pnd, &nt, abtRx, &szRx)) {
00135     nfc_perror (pnd, "nfc_target_init");
00136     ERR("Could not come out of auto-emulation, no command was received");
00137     return EXIT_FAILURE;
00138   }
00139 
00140   if (!quiet_output) {
00141     printf ("Received data: ");
00142     print_hex (abtRx, szRx);
00143   }
00144 
00145 //Receiving data: e0  40
00146 //= RATS, FSD=48
00147 //Actually PN532 already sent back the ATS so nothing to send now
00148   receive_bytes();
00149 //Receiving data: 00  a4  04  00  06  e1  03  e1  03  e1  03
00150 //= App Select by name "e103e103e103"
00151   send_bytes((const byte_t*)"\x6a\x87",2);
00152   receive_bytes();
00153 //Receiving data: 00  a4  04  00  06  e1  03  e1  03  e1  03
00154 //= App Select by name "e103e103e103"
00155   send_bytes((const byte_t*)"\x6a\x87",2);
00156   receive_bytes();
00157 //Receiving data: 00  a4  04  00  07  d2  76  00  00  85  01  00
00158 //= App Select by name "D2760000850100"
00159   send_bytes((const byte_t*)"\x90\x00",2);
00160   receive_bytes();
00161 //Receiving data: 00  a4  00  00  02  e1  03
00162 //= Select CC
00163   send_bytes((const byte_t*)"\x90\x00",2);
00164   receive_bytes();
00165 //Receiving data: 00  b0  00  00  0f
00166 //= ReadBinary CC
00167 //We send CC + OK
00168   send_bytes((const byte_t*)"\x00\x0f\x10\x00\x3b\x00\x34\x04\x06\xe1\x04\x0e\xe0\x00\x00\x90\x00",17);
00169   receive_bytes();
00170 //Receiving data: 00  a4  00  00  02  e1  04
00171 //= Select NDEF
00172   send_bytes((const byte_t*)"\x90\x00",2);
00173   receive_bytes();
00174 //Receiving data: 00  b0  00  00  02
00175 //=  Read first 2 NDEF bytes
00176 //Sent NDEF Length=0x21
00177   send_bytes((const byte_t*)"\x00\x21\x90\x00",4);
00178   receive_bytes();
00179 //Receiving data: 00  b0  00  02  21
00180 //= Read remaining of NDEF file
00181   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);
00182 
00183   nfc_disconnect(pnd);
00184   exit (EXIT_SUCCESS);
00185 }