Codebase list libfreefare / upstream/1.8.0+git20210122.1.2b5ad9c
Import upstream version 1.8.0+git20210122.1.2b5ad9c Debian Janitor 2 years ago
33 changed file(s) with 1433 addition(s) and 307 deletion(s). Raw diff Collapse all Expand all
66 *.lo
77 *.o
88 *~
9 .vs/
10 CMakeSettings.json
911 Doxyfile
1012 INSTALL
1113 aclocal.m4
00 language: c
11
2 compiler:
3 - clang
4 - gcc
2 matrix:
3 include:
4 - os: windows
5 compiler:
6 - clang
7 before_install:
8 - mkdir build && cd build && wget "https://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/1.2.6.0/libusb-win32-bin-1.2.6.0.zip" && 7z x libusb-win32-bin-1.2.6.0.zip -o"$PROGRAMFILES" && mv "$PROGRAMFILES/libusb-win32-bin-1.2.6.0" "$PROGRAMFILES/libusb-win32"
9 install:
10 choco install doxygen.install ninja
11 script:
12 cmake -GNinja .. && cmake --build .
513
6 env:
7 - BLD=cmake
8 - BLD=autoconf
14 - os: linux
15 dist: bionic
16 compiler:
17 - clang
18 addons:
19 apt:
20 packages:
21 - libusb-dev
22 - doxygen
23 - cmake
24 script:
25 - mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install
26
27 - os: linux
28 dist: bionic
29 compiler:
30 - clang
31 addons:
32 apt:
33 packages:
34 - libusb-dev
35 - doxygen
36 script:
37 - autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install
938
10 addons:
11 apt:
12 packages:
13 - libusb-dev
14 - doxygen
15 - cmake
39 - os: linux
40 dist: bionic
41 compiler:
42 - gcc
43 addons:
44 apt:
45 packages:
46 - libusb-dev
47 - doxygen
48 - cmake
49 script:
50 - mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install
1651
17 script:
18 - if [ $BLD == autoconf ]; then autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install; fi
19 - if [ $BLD == cmake ]; then mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install; fi
52 - os: linux
53 dist: bionic
54 compiler:
55 - gcc
56 addons:
57 apt:
58 packages:
59 - libusb-dev
60 - doxygen
61 script:
62 - autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install
63
64 - os: osx
65 osx_image: xcode12
66 compiler:
67 - clang
68 before_install:
69 - brew install doxygen libusb-compat
70 script:
71 - mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install
72
73 - os: osx
74 osx_image: xcode12
75 compiler:
76 - clang
77 before_install:
78 - brew install doxygen libusb-compat m4
79 script:
80 - autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install
1717
1818 # config.h
1919 IF(WIN32)
20 SET(LIBNFC_SYSCONFDIR "./config" CACHE PATH "libnfc configuration directory")
2021 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake/config_windows.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
21 SET(LIBNFC_SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/config" CACHE PATH "libnfc configuration directory")
2222 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/contrib/win32)
23 IF(NOT MINGW)
24 SET(CMAKE_C_FLAGS "-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE ${CMAKE_C_FLAGS}")
25 ENDIF(NOT MINGW)
2326 ELSE(WIN32)
2427 SET(_XOPEN_SOURCE 600)
2528 SET(SYSCONFDIR "/etc" CACHE PATH "System configuration directory")
137140 IF(LIBNFC_DRIVER_PN53X_USB)
138141 SET(PKG_REQ ${PKG_REQ} "libusb")
139142 ENDIF(LIBNFC_DRIVER_PN53X_USB)
143 IF(LIBNFC_DRIVER_ACR122_USB)
144 SET(PKG_REQ ${PKG_REQ} "libusb")
145 ENDIF(LIBNFC_DRIVER_ACR122_USB)
140146 IF(LIBNFC_DRIVER_PCSC)
141147 SET(PKG_REQ ${PKG_REQ} "libpcsclite")
142 ENDIF(LIBNFC_DRIVER_ACR122)
148 ENDIF(LIBNFC_DRIVER_PCSC)
143149 IF(LIBNFC_DRIVER_ACR122_PCSC)
144150 SET(PKG_REQ ${PKG_REQ} "libpcsclite")
145151 ENDIF(LIBNFC_DRIVER_ACR122_PCSC)
200206 SET(RC_COMMENT "${PACKAGE_NAME} library")
201207 SET(RC_INTERNAL_NAME "${PACKAGE_NAME} ${WIN32_MODE}")
202208 SET(RC_ORIGINAL_NAME ${PACKAGE_NAME}.dll)
203 SET(RC_FILE_TYPE VFT_DLL)
209 # RC_FILE_TYPE: VFT_DLL
210 SET(RC_FILE_TYPE 0x00000002L)
204211 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/contrib/win32/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/windows/libnfc.rc @ONLY)
205212 ENDIF(WIN32)
206213
11
22 AM_CFLAGS = $(LIBNFC_CFLAGS)
33
4 SUBDIRS = libnfc utils examples include contrib cmake test
4 SUBDIRS = libnfc utils
5
6 if EXAMPLE_ENABLED
7 SUBDIRS += examples
8 endif
9
10 SUBDIRS += include contrib cmake test
511
612 pkgconfigdir = $(libdir)/pkgconfig
713 pkgconfig_DATA = libnfc.pc
3939
4040 * acr122_pcsc:
4141
42 - pcsc-lite http://pcsclite.alioth.debian.org/
42 - pcsc-lite https://pcsclite.apdu.fr/
4343 - pcsc:
4444
4545 - Support build with pcsc driver, which can be using all compatible readers, Feitian R502 and bR500 already passed the test.
2525
2626 IF(NOT LIBUSB_FOUND)
2727 IF(WIN32)
28 FIND_PATH(LIBUSB_INCLUDE_DIRS lusb0_usb.h "$ENV{ProgramFiles}/LibUSB-Win32/include" NO_SYSTEM_ENVIRONMENT_PATH)
29 FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramFiles}/LibUSB-Win32/lib/gcc")
30 SET(LIBUSB_LIBRARY_DIR "$ENV{ProgramFiles}/LibUSB-Win32/bin/x86/")
28 IF(MINGW)
29 FIND_PATH(LIBUSB_INCLUDE_DIRS lusb0_usb.h "${CMAKE_CURRENT_BINARY_DIR}/LibUSB-Win32/include" NO_SYSTEM_ENVIRONMENT_PATH)
30 FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "${CMAKE_CURRENT_BINARY_DIR}/LibUSB-Win32/lib/gcc")
31 SET(LIBUSB_LIBRARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/LibUSB-Win32/bin/x86/")
32 ELSE(MINGW)
33 FIND_PATH(LIBUSB_INCLUDE_DIRS lusb0_usb.h "$ENV{ProgramW6432}/libusb-win32/include" NO_SYSTEM_ENVIRONMENT_PATH)
34 FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramW6432}/libusb-win32/lib/msvc_x64")
35 SET(LIBUSB_LIBRARY_DIR "$ENV{ProgramW6432}/libusb-win32/bin/amd64/")
36 ENDIF(MINGW)
3137 # Must fix up variable to avoid backslashes during packaging
3238 STRING(REGEX REPLACE "\\\\" "/" LIBUSB_LIBRARY_DIR ${LIBUSB_LIBRARY_DIR})
3339 ELSE(WIN32)
22 SET(LIBNFC_DRIVER_ACR122_USB ON CACHE BOOL "Enable ACR122 support (Direct USB connection)")
33 SET(LIBNFC_DRIVER_ACR122S ON CACHE BOOL "Enable ACR122S support (Use serial port)")
44 SET(LIBNFC_DRIVER_ARYGON ON CACHE BOOL "Enable ARYGON support (Use serial port)")
5 IF(WIN32)
5 IF(UNIX AND NOT APPLE)
6 SET(LIBNFC_DRIVER_PN532_I2C ON CACHE BOOL "Enable PN532 I2C support (Use I2C bus)")
7 SET(LIBNFC_DRIVER_PN532_SPI ON CACHE BOOL "Enable PN532 SPI support (Use SPI bus)")
8 ELSE(UNIX AND NOT APPLE)
69 SET(LIBNFC_DRIVER_PN532_I2C OFF CACHE BOOL "Enable PN532 I2C support (Use I2C bus)")
710 SET(LIBNFC_DRIVER_PN532_SPI OFF CACHE BOOL "Enable PN532 SPI support (Use SPI bus)")
8 ELSE(WIN32)
9 SET(LIBNFC_DRIVER_PN532_I2C ON CACHE BOOL "Enable PN532 I2C support (Use I2C bus)")
10 SET(LIBNFC_DRIVER_PN532_SPI ON CACHE BOOL "Enable PN532 SPI support (Use SPI bus)")
11 ENDIF(WIN32)
11 ENDIF(UNIX AND NOT APPLE)
1212 SET(LIBNFC_DRIVER_PN532_UART ON CACHE BOOL "Enable PN532 UART support (Use serial port)")
1313 SET(LIBNFC_DRIVER_PN53X_USB ON CACHE BOOL "Enable PN531 and PN531 USB support (Depends on libusb)")
1414
6767 SET(USB_REQUIRED TRUE)
6868 ENDIF(LIBNFC_DRIVER_PN53X_USB)
6969
70 IF(LIBNFC_DRIVER_ACR122_USB)
71 FIND_PACKAGE(LIBUSB REQUIRED)
72 ADD_DEFINITIONS("-DDRIVER_ACR122_USB_ENABLED")
73 SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/acr122_usb")
74 SET(USB_REQUIRED TRUE)
75 ENDIF(LIBNFC_DRIVER_ACR122_USB)
76
7077 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/libnfc/drivers)
156156 fi
157157 AM_CONDITIONAL(DOC_ENABLED, [test x"$enable_doc" = xyes])
158158
159 # Example build (default: yes)
160 AC_ARG_ENABLE([example],AS_HELP_STRING([--enable-example],[Enable example build.]),[enable_example=$enableval],[enable_example="yes"])
161
162 AC_MSG_CHECKING(for example build)
163 AC_MSG_RESULT($enable_example)
164
165 AM_CONDITIONAL(EXAMPLE_ENABLED, [test x"$enable_example" = xyes])
166
159167 # Dependencies
160168 PKG_CONFIG_REQUIRES=""
161169
174182 fi
175183 AM_CONDITIONAL([WITH_CUTTER], [test "$ac_cv_use_cutter" != "no"])
176184
185 if test x"$enable_example" = "xyes"
186 then
177187 AC_CHECK_READLINE
188 fi
178189
179190 # Help us to write great code ;-)
180191 CFLAGS="$CFLAGS -Wall -pedantic -Wextra"
0 /*
1 * Dirent interface for Microsoft Visual Studio
2 *
3 * Copyright (C) 2006-2012 Toni Ronkko
4 * This file is part of dirent. Dirent may be freely distributed
5 * under the MIT license. For all details and documentation, see
6 * https://github.com/tronkko/dirent
7 */
8 #ifndef DIRENT_H
9 #define DIRENT_H
10
11 /*
12 * Include windows.h without Windows Sockets 1.1 to prevent conflicts with
13 * Windows Sockets 2.0.
14 */
15 #ifndef WIN32_LEAN_AND_MEAN
16 # define WIN32_LEAN_AND_MEAN
17 #endif
18 #include <windows.h>
19
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <wchar.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <malloc.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <errno.h>
29
30 /* Indicates that d_type field is available in dirent structure */
31 #define _DIRENT_HAVE_D_TYPE
32
33 /* Indicates that d_namlen field is available in dirent structure */
34 #define _DIRENT_HAVE_D_NAMLEN
35
36 /* Entries missing from MSVC 6.0 */
37 #if !defined(FILE_ATTRIBUTE_DEVICE)
38 # define FILE_ATTRIBUTE_DEVICE 0x40
39 #endif
40
41 /* File type and permission flags for stat(), general mask */
42 #if !defined(S_IFMT)
43 # define S_IFMT _S_IFMT
44 #endif
45
46 /* Directory bit */
47 #if !defined(S_IFDIR)
48 # define S_IFDIR _S_IFDIR
49 #endif
50
51 /* Character device bit */
52 #if !defined(S_IFCHR)
53 # define S_IFCHR _S_IFCHR
54 #endif
55
56 /* Pipe bit */
57 #if !defined(S_IFFIFO)
58 # define S_IFFIFO _S_IFFIFO
59 #endif
60
61 /* Regular file bit */
62 #if !defined(S_IFREG)
63 # define S_IFREG _S_IFREG
64 #endif
65
66 /* Read permission */
67 #if !defined(S_IREAD)
68 # define S_IREAD _S_IREAD
69 #endif
70
71 /* Write permission */
72 #if !defined(S_IWRITE)
73 # define S_IWRITE _S_IWRITE
74 #endif
75
76 /* Execute permission */
77 #if !defined(S_IEXEC)
78 # define S_IEXEC _S_IEXEC
79 #endif
80
81 /* Pipe */
82 #if !defined(S_IFIFO)
83 # define S_IFIFO _S_IFIFO
84 #endif
85
86 /* Block device */
87 #if !defined(S_IFBLK)
88 # define S_IFBLK 0
89 #endif
90
91 /* Link */
92 #if !defined(S_IFLNK)
93 # define S_IFLNK 0
94 #endif
95
96 /* Socket */
97 #if !defined(S_IFSOCK)
98 # define S_IFSOCK 0
99 #endif
100
101 /* Read user permission */
102 #if !defined(S_IRUSR)
103 # define S_IRUSR S_IREAD
104 #endif
105
106 /* Write user permission */
107 #if !defined(S_IWUSR)
108 # define S_IWUSR S_IWRITE
109 #endif
110
111 /* Execute user permission */
112 #if !defined(S_IXUSR)
113 # define S_IXUSR 0
114 #endif
115
116 /* Read group permission */
117 #if !defined(S_IRGRP)
118 # define S_IRGRP 0
119 #endif
120
121 /* Write group permission */
122 #if !defined(S_IWGRP)
123 # define S_IWGRP 0
124 #endif
125
126 /* Execute group permission */
127 #if !defined(S_IXGRP)
128 # define S_IXGRP 0
129 #endif
130
131 /* Read others permission */
132 #if !defined(S_IROTH)
133 # define S_IROTH 0
134 #endif
135
136 /* Write others permission */
137 #if !defined(S_IWOTH)
138 # define S_IWOTH 0
139 #endif
140
141 /* Execute others permission */
142 #if !defined(S_IXOTH)
143 # define S_IXOTH 0
144 #endif
145
146 /* Maximum length of file name */
147 #if !defined(PATH_MAX)
148 # define PATH_MAX MAX_PATH
149 #endif
150 #if !defined(FILENAME_MAX)
151 # define FILENAME_MAX MAX_PATH
152 #endif
153 #if !defined(NAME_MAX)
154 # define NAME_MAX FILENAME_MAX
155 #endif
156
157 /* File type flags for d_type */
158 #define DT_UNKNOWN 0
159 #define DT_REG S_IFREG
160 #define DT_DIR S_IFDIR
161 #define DT_FIFO S_IFIFO
162 #define DT_SOCK S_IFSOCK
163 #define DT_CHR S_IFCHR
164 #define DT_BLK S_IFBLK
165 #define DT_LNK S_IFLNK
166
167 /* Macros for converting between st_mode and d_type */
168 #define IFTODT(mode) ((mode) & S_IFMT)
169 #define DTTOIF(type) (type)
170
171 /*
172 * File type macros. Note that block devices, sockets and links cannot be
173 * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
174 * only defined for compatibility. These macros should always return false
175 * on Windows.
176 */
177 #if !defined(S_ISFIFO)
178 # define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
179 #endif
180 #if !defined(S_ISDIR)
181 # define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
182 #endif
183 #if !defined(S_ISREG)
184 # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
185 #endif
186 #if !defined(S_ISLNK)
187 # define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
188 #endif
189 #if !defined(S_ISSOCK)
190 # define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
191 #endif
192 #if !defined(S_ISCHR)
193 # define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
194 #endif
195 #if !defined(S_ISBLK)
196 # define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
197 #endif
198
199 /* Return the exact length of the file name without zero terminator */
200 #define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
201
202 /* Return the maximum size of a file name */
203 #define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1)
204
205
206 #ifdef __cplusplus
207 extern "C" {
208 #endif
209
210
211 /* Wide-character version */
212 struct _wdirent {
213 /* Always zero */
214 long d_ino;
215
216 /* File position within stream */
217 long d_off;
218
219 /* Structure size */
220 unsigned short d_reclen;
221
222 /* Length of name without \0 */
223 size_t d_namlen;
224
225 /* File type */
226 int d_type;
227
228 /* File name */
229 wchar_t d_name[PATH_MAX+1];
230 };
231 typedef struct _wdirent _wdirent;
232
233 struct _WDIR {
234 /* Current directory entry */
235 struct _wdirent ent;
236
237 /* Private file data */
238 WIN32_FIND_DATAW data;
239
240 /* True if data is valid */
241 int cached;
242
243 /* Win32 search handle */
244 HANDLE handle;
245
246 /* Initial directory name */
247 wchar_t *patt;
248 };
249 typedef struct _WDIR _WDIR;
250
251 /* Multi-byte character version */
252 struct dirent {
253 /* Always zero */
254 long d_ino;
255
256 /* File position within stream */
257 long d_off;
258
259 /* Structure size */
260 unsigned short d_reclen;
261
262 /* Length of name without \0 */
263 size_t d_namlen;
264
265 /* File type */
266 int d_type;
267
268 /* File name */
269 char d_name[PATH_MAX+1];
270 };
271 typedef struct dirent dirent;
272
273 struct DIR {
274 struct dirent ent;
275 struct _WDIR *wdirp;
276 };
277 typedef struct DIR DIR;
278
279
280 /* Dirent functions */
281 static DIR *opendir (const char *dirname);
282 static _WDIR *_wopendir (const wchar_t *dirname);
283
284 static struct dirent *readdir (DIR *dirp);
285
286 static int readdir_r(
287 DIR *dirp, struct dirent *entry, struct dirent **result);
288
289 static int closedir (DIR *dirp);
290 static int _wclosedir (_WDIR *dirp);
291
292 /* For compatibility with Symbian */
293 #define wdirent _wdirent
294 #define WDIR _WDIR
295 #define wopendir _wopendir
296 #define wreaddir _wreaddir
297 #define wclosedir _wclosedir
298 #define wrewinddir _wrewinddir
299
300
301 /* Internal utility functions */
302 static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
303 static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
304
305 static int dirent_mbstowcs_s(
306 size_t *pReturnValue,
307 wchar_t *wcstr,
308 size_t sizeInWords,
309 const char *mbstr,
310 size_t count);
311
312 static int dirent_wcstombs_s(
313 size_t *pReturnValue,
314 char *mbstr,
315 size_t sizeInBytes,
316 const wchar_t *wcstr,
317 size_t count);
318
319 static void dirent_set_errno (int error);
320
321
322 /*
323 * Open directory stream DIRNAME for read and return a pointer to the
324 * internal working area that is used to retrieve individual directory
325 * entries.
326 */
327 static _WDIR*
328 _wopendir(
329 const wchar_t *dirname)
330 {
331 _WDIR *dirp = NULL;
332 int error;
333
334 /* Must have directory name */
335 if (dirname == NULL || dirname[0] == '\0') {
336 dirent_set_errno (ENOENT);
337 return NULL;
338 }
339
340 /* Allocate new _WDIR structure */
341 dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
342 if (dirp != NULL) {
343 DWORD n;
344
345 /* Reset _WDIR structure */
346 dirp->handle = INVALID_HANDLE_VALUE;
347 dirp->patt = NULL;
348 dirp->cached = 0;
349
350 /* Compute the length of full path plus zero terminator
351 *
352 * Note that on WinRT there's no way to convert relative paths
353 * into absolute paths, so just assume it is an absolute path.
354 */
355 # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
356 n = wcslen(dirname);
357 # else
358 n = GetFullPathNameW (dirname, 0, NULL, NULL);
359 # endif
360
361 /* Allocate room for absolute directory name and search pattern */
362 dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
363 if (dirp->patt) {
364
365 /*
366 * Convert relative directory name to an absolute one. This
367 * allows rewinddir() to function correctly even when current
368 * working directory is changed between opendir() and rewinddir().
369 *
370 * Note that on WinRT there's no way to convert relative paths
371 * into absolute paths, so just assume it is an absolute path.
372 */
373 # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
374 wcsncpy_s(dirp->patt, n+1, dirname, n);
375 # else
376 n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
377 # endif
378 if (n > 0) {
379 wchar_t *p;
380
381 /* Append search pattern \* to the directory name */
382 p = dirp->patt + n;
383 if (dirp->patt < p) {
384 switch (p[-1]) {
385 case '\\':
386 case '/':
387 case ':':
388 /* Directory ends in path separator, e.g. c:\temp\ */
389 /*NOP*/;
390 break;
391
392 default:
393 /* Directory name doesn't end in path separator */
394 *p++ = '\\';
395 }
396 }
397 *p++ = '*';
398 *p = '\0';
399
400 /* Open directory stream and retrieve the first entry */
401 if (dirent_first (dirp)) {
402 /* Directory stream opened successfully */
403 error = 0;
404 } else {
405 /* Cannot retrieve first entry */
406 error = 1;
407 dirent_set_errno (ENOENT);
408 }
409
410 } else {
411 /* Cannot retrieve full path name */
412 dirent_set_errno (ENOENT);
413 error = 1;
414 }
415
416 } else {
417 /* Cannot allocate memory for search pattern */
418 error = 1;
419 }
420
421 } else {
422 /* Cannot allocate _WDIR structure */
423 error = 1;
424 }
425
426 /* Clean up in case of error */
427 if (error && dirp) {
428 _wclosedir (dirp);
429 dirp = NULL;
430 }
431
432 return dirp;
433 }
434
435 /*
436 * Close directory stream opened by opendir() function. This invalidates the
437 * DIR structure as well as any directory entry read previously by
438 * _wreaddir().
439 */
440 static int
441 _wclosedir(
442 _WDIR *dirp)
443 {
444 int ok;
445 if (dirp) {
446
447 /* Release search handle */
448 if (dirp->handle != INVALID_HANDLE_VALUE) {
449 FindClose (dirp->handle);
450 dirp->handle = INVALID_HANDLE_VALUE;
451 }
452
453 /* Release search pattern */
454 if (dirp->patt) {
455 free (dirp->patt);
456 dirp->patt = NULL;
457 }
458
459 /* Release directory structure */
460 free (dirp);
461 ok = /*success*/0;
462
463 } else {
464
465 /* Invalid directory stream */
466 dirent_set_errno (EBADF);
467 ok = /*failure*/-1;
468
469 }
470 return ok;
471 }
472
473 /* Get first directory entry (internal) */
474 static WIN32_FIND_DATAW*
475 dirent_first(
476 _WDIR *dirp)
477 {
478 WIN32_FIND_DATAW *datap;
479
480 /* Open directory and retrieve the first entry */
481 dirp->handle = FindFirstFileExW(
482 dirp->patt, FindExInfoStandard, &dirp->data,
483 FindExSearchNameMatch, NULL, 0);
484 if (dirp->handle != INVALID_HANDLE_VALUE) {
485
486 /* a directory entry is now waiting in memory */
487 datap = &dirp->data;
488 dirp->cached = 1;
489
490 } else {
491
492 /* Failed to re-open directory: no directory entry in memory */
493 dirp->cached = 0;
494 datap = NULL;
495
496 }
497 return datap;
498 }
499
500 /*
501 * Get next directory entry (internal).
502 *
503 * Returns
504 */
505 static WIN32_FIND_DATAW*
506 dirent_next(
507 _WDIR *dirp)
508 {
509 WIN32_FIND_DATAW *p;
510
511 /* Get next directory entry */
512 if (dirp->cached != 0) {
513
514 /* A valid directory entry already in memory */
515 p = &dirp->data;
516 dirp->cached = 0;
517
518 } else if (dirp->handle != INVALID_HANDLE_VALUE) {
519
520 /* Get the next directory entry from stream */
521 if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
522 /* Got a file */
523 p = &dirp->data;
524 } else {
525 /* The very last entry has been processed or an error occurred */
526 FindClose (dirp->handle);
527 dirp->handle = INVALID_HANDLE_VALUE;
528 p = NULL;
529 }
530
531 } else {
532
533 /* End of directory stream reached */
534 p = NULL;
535
536 }
537
538 return p;
539 }
540
541 /*
542 * Open directory stream using plain old C-string.
543 */
544 static DIR*
545 opendir(
546 const char *dirname)
547 {
548 struct DIR *dirp;
549 int error;
550
551 /* Must have directory name */
552 if (dirname == NULL || dirname[0] == '\0') {
553 dirent_set_errno (ENOENT);
554 return NULL;
555 }
556
557 /* Allocate memory for DIR structure */
558 dirp = (DIR*) malloc (sizeof (struct DIR));
559 if (dirp) {
560 wchar_t wname[PATH_MAX + 1];
561 size_t n;
562
563 /* Convert directory name to wide-character string */
564 error = dirent_mbstowcs_s(
565 &n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1);
566 if (!error) {
567
568 /* Open directory stream using wide-character name */
569 dirp->wdirp = _wopendir (wname);
570 if (dirp->wdirp) {
571 /* Directory stream opened */
572 error = 0;
573 } else {
574 /* Failed to open directory stream */
575 error = 1;
576 }
577
578 } else {
579 /*
580 * Cannot convert file name to wide-character string. This
581 * occurs if the string contains invalid multi-byte sequences or
582 * the output buffer is too small to contain the resulting
583 * string.
584 */
585 error = 1;
586 }
587
588 } else {
589 /* Cannot allocate DIR structure */
590 error = 1;
591 }
592
593 /* Clean up in case of error */
594 if (error && dirp) {
595 free (dirp);
596 dirp = NULL;
597 }
598
599 return dirp;
600 }
601
602 /*
603 * Read next directory entry.
604 */
605 static struct dirent*
606 readdir(
607 DIR *dirp)
608 {
609 struct dirent *entry;
610
611 /*
612 * Read directory entry to buffer. We can safely ignore the return value
613 * as entry will be set to NULL in case of error.
614 */
615 (void) readdir_r (dirp, &dirp->ent, &entry);
616
617 /* Return pointer to statically allocated directory entry */
618 return entry;
619 }
620
621 /*
622 * Read next directory entry into called-allocated buffer.
623 *
624 * Returns zero on success. If the end of directory stream is reached, then
625 * sets result to NULL and returns zero.
626 */
627 static int
628 readdir_r(
629 DIR *dirp,
630 struct dirent *entry,
631 struct dirent **result)
632 {
633 WIN32_FIND_DATAW *datap;
634
635 /* Read next directory entry */
636 datap = dirent_next (dirp->wdirp);
637 if (datap) {
638 size_t n;
639 int error;
640
641 /* Attempt to convert file name to multi-byte string */
642 error = dirent_wcstombs_s(
643 &n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1);
644
645 /*
646 * If the file name cannot be represented by a multi-byte string,
647 * then attempt to use old 8+3 file name. This allows traditional
648 * Unix-code to access some file names despite of unicode
649 * characters, although file names may seem unfamiliar to the user.
650 *
651 * Be ware that the code below cannot come up with a short file
652 * name unless the file system provides one. At least
653 * VirtualBox shared folders fail to do this.
654 */
655 if (error && datap->cAlternateFileName[0] != '\0') {
656 error = dirent_wcstombs_s(
657 &n, entry->d_name, PATH_MAX + 1,
658 datap->cAlternateFileName, PATH_MAX + 1);
659 }
660
661 if (!error) {
662 DWORD attr;
663
664 /* Length of file name excluding zero terminator */
665 entry->d_namlen = n - 1;
666
667 /* File attributes */
668 attr = datap->dwFileAttributes;
669 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
670 entry->d_type = DT_CHR;
671 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
672 entry->d_type = DT_DIR;
673 } else {
674 entry->d_type = DT_REG;
675 }
676
677 /* Reset dummy fields */
678 entry->d_ino = 0;
679 entry->d_off = 0;
680 entry->d_reclen = sizeof (struct dirent);
681
682 } else {
683
684 /*
685 * Cannot convert file name to multi-byte string so construct
686 * an erroneous directory entry and return that. Note that
687 * we cannot return NULL as that would stop the processing
688 * of directory entries completely.
689 */
690 entry->d_name[0] = '?';
691 entry->d_name[1] = '\0';
692 entry->d_namlen = 1;
693 entry->d_type = DT_UNKNOWN;
694 entry->d_ino = 0;
695 entry->d_off = -1;
696 entry->d_reclen = 0;
697
698 }
699
700 /* Return pointer to directory entry */
701 *result = entry;
702
703 } else {
704
705 /* No more directory entries */
706 *result = NULL;
707
708 }
709
710 return /*OK*/0;
711 }
712
713 /*
714 * Close directory stream.
715 */
716 static int
717 closedir(
718 DIR *dirp)
719 {
720 int ok;
721 if (dirp) {
722
723 /* Close wide-character directory stream */
724 ok = _wclosedir (dirp->wdirp);
725 dirp->wdirp = NULL;
726
727 /* Release multi-byte character version */
728 free (dirp);
729
730 } else {
731
732 /* Invalid directory stream */
733 dirent_set_errno (EBADF);
734 ok = /*failure*/-1;
735
736 }
737 return ok;
738 }
739
740 /* Convert multi-byte string to wide character string */
741 static int
742 dirent_mbstowcs_s(
743 size_t *pReturnValue,
744 wchar_t *wcstr,
745 size_t sizeInWords,
746 const char *mbstr,
747 size_t count)
748 {
749 int error;
750
751 #if defined(_MSC_VER) && _MSC_VER >= 1400
752
753 /* Microsoft Visual Studio 2005 or later */
754 error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
755
756 #else
757
758 /* Older Visual Studio or non-Microsoft compiler */
759 size_t n;
760
761 /* Convert to wide-character string (or count characters) */
762 n = mbstowcs (wcstr, mbstr, sizeInWords);
763 if (!wcstr || n < count) {
764
765 /* Zero-terminate output buffer */
766 if (wcstr && sizeInWords) {
767 if (n >= sizeInWords) {
768 n = sizeInWords - 1;
769 }
770 wcstr[n] = 0;
771 }
772
773 /* Length of resulting multi-byte string WITH zero terminator */
774 if (pReturnValue) {
775 *pReturnValue = n + 1;
776 }
777
778 /* Success */
779 error = 0;
780
781 } else {
782
783 /* Could not convert string */
784 error = 1;
785
786 }
787
788 #endif
789
790 return error;
791 }
792
793 /* Convert wide-character string to multi-byte string */
794 static int
795 dirent_wcstombs_s(
796 size_t *pReturnValue,
797 char *mbstr,
798 size_t sizeInBytes, /* max size of mbstr */
799 const wchar_t *wcstr,
800 size_t count)
801 {
802 int error;
803
804 #if defined(_MSC_VER) && _MSC_VER >= 1400
805
806 /* Microsoft Visual Studio 2005 or later */
807 error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
808
809 #else
810
811 /* Older Visual Studio or non-Microsoft compiler */
812 size_t n;
813
814 /* Convert to multi-byte string (or count the number of bytes needed) */
815 n = wcstombs (mbstr, wcstr, sizeInBytes);
816 if (!mbstr || n < count) {
817
818 /* Zero-terminate output buffer */
819 if (mbstr && sizeInBytes) {
820 if (n >= sizeInBytes) {
821 n = sizeInBytes - 1;
822 }
823 mbstr[n] = '\0';
824 }
825
826 /* Length of resulting multi-bytes string WITH zero-terminator */
827 if (pReturnValue) {
828 *pReturnValue = n + 1;
829 }
830
831 /* Success */
832 error = 0;
833
834 } else {
835
836 /* Cannot convert string */
837 error = 1;
838
839 }
840
841 #endif
842
843 return error;
844 }
845
846 /* Set errno variable */
847 static void
848 dirent_set_errno(
849 int error)
850 {
851 #if defined(_MSC_VER) && _MSC_VER >= 1400
852
853 /* Microsoft Visual Studio 2005 and later */
854 _set_errno (error);
855
856 #else
857
858 /* Non-Microsoft compiler or older Microsoft compiler */
859 errno = error;
860
861 #endif
862 }
863
864
865 #ifdef __cplusplus
866 }
867 #endif
868 #endif /*DIRENT_H*/
869
0 #include "getopt.h" // make sure you construct the header file as dictated above
1
2 /*
3 * Copyright (c) 1987, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include <string.h>
36 #include <stdio.h>
37
38 int opterr = 1, /* if error message should be printed */
39 optind = 1, /* index into parent argv vector */
40 optopt, /* character checked for validity */
41 optreset; /* reset getopt */
42 char *optarg; /* argument associated with option */
43
44 #define BADCH (int)'?'
45 #define BADARG (int)':'
46 #define EMSG ""
47
48 /*
49 * getopt --
50 * Parse argc/argv argument vector.
51 */
52 int getopt(int nargc, char * const nargv[], const char *ostr)
53 {
54 static char *place = EMSG; /* option letter processing */
55 const char *oli; /* option letter list index */
56
57 if (optreset || !*place) { /* update scanning pointer */
58 optreset = 0;
59 if (optind >= nargc || *(place = nargv[optind]) != '-') {
60 place = EMSG;
61 return (-1);
62 }
63 if (place[1] && *++place == '-') { /* found "--" */
64 ++optind;
65 place = EMSG;
66 return (-1);
67 }
68 } /* option letter okay? */
69 if ((optopt = (int)*place++) == (int)':' ||
70 !(oli = strchr(ostr, optopt))) {
71 /*
72 * if the user didn't specify '-' as an option,
73 * assume it means -1.
74 */
75 if (optopt == (int)'-')
76 return (-1);
77 if (!*place)
78 ++optind;
79 if (opterr && *ostr != ':')
80 (void)printf("illegal option -- %c\n", optopt);
81 return (BADCH);
82 }
83 if (*++oli != ':') { /* don't need argument */
84 optarg = NULL;
85 if (!*place)
86 ++optind;
87 }
88 else { /* need an argument */
89 if (*place) /* no white space */
90 optarg = place;
91 else if (nargc <= ++optind) { /* no arg */
92 place = EMSG;
93 if (*ostr == ':')
94 return (BADARG);
95 if (opterr)
96 (void)printf("option requires an argument -- %c\n", optopt);
97 return (BADCH);
98 }
99 else /* white space */
100 optarg = nargv[optind];
101 place = EMSG;
102 ++optind;
103 }
104 return (optopt); /* dump back option letter */
105 }
0 #ifndef GETOPT_H
1
2 #define GETOPT_H
3
4 extern int opterr; /* if error message should be printed */
5 extern int optind; /* index into parent argv vector */
6 extern int optopt; /* character checked for validity */
7 extern int optreset; /* reset getopt */
8 extern char *optarg; /* argument associated with option */
9
10 int getopt(int nargc, char * const nargv[], const char *ostr);
11
12 #endif
182182 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Timeouts are set to %lu ms", timeout_ms);
183183
184184 // TODO Enhance the reception method
185 // - According to MSDN, it could be better to implement nfc_abort_command() mecanism using Cancello()
185 // - According to MSDN, it could be better to implement nfc_abort_command() mechanism using Cancello()
186186 volatile bool *abort_flag_p = (volatile bool *)abort_p;
187187 do {
188188 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "ReadFile");
3838 nfc_device_get_supported_baud_rate_target_mode
3939 nfc_device_set_property_int
4040 nfc_device_set_property_bool
41 nfc_emulate_target
4142 iso14443a_crc
4243 iso14443a_crc_append
4344 iso14443b_crc
4950 str_nfc_modulation_type
5051 str_nfc_baud_rate
5152 str_nfc_target
53 pn53x_transceive
54 pn532_SAMConfiguration
55 pn53x_read_register
56 pn53x_write_register
0 LIBRARY nfc
1 VERSION 1.7
2
3 EXPORTS
4 nfc_init
5 nfc_exit
6 nfc_register_driver
7 nfc_open
8 nfc_close
9 nfc_abort_command
10 nfc_list_devices
11 nfc_idle
12 nfc_initiator_init
13 nfc_initiator_init_secure_element
14 nfc_initiator_select_passive_target
15 nfc_initiator_list_passive_targets
16 nfc_initiator_poll_target
17 nfc_initiator_select_dep_target
18 nfc_initiator_poll_dep_target
19 nfc_initiator_deselect_target
20 nfc_initiator_transceive_bytes
21 nfc_initiator_transceive_bits
22 nfc_initiator_transceive_bytes_timed
23 nfc_initiator_transceive_bits_timed
24 nfc_initiator_target_is_present
25 nfc_target_init
26 nfc_target_send_bytes
27 nfc_target_receive_bytes
28 nfc_target_send_bits
29 nfc_target_receive_bits
30 nfc_strerror
31 nfc_strerror_r
32 nfc_perror
33 nfc_device_get_last_error
34 nfc_device_get_name
35 nfc_device_get_connstring
36 nfc_device_get_supported_modulation
37 nfc_device_get_supported_baud_rate
38 nfc_device_get_supported_baud_rate_target_mode
39 nfc_device_set_property_int
40 nfc_device_set_property_bool
41 nfc_emulate_target
42 iso14443a_crc
43 iso14443a_crc_append
44 iso14443b_crc
45 iso14443b_crc_append
46 iso14443a_locate_historical_bytes
47 nfc_free
48 nfc_version
49 nfc_device_get_information_about
50 str_nfc_modulation_type
51 str_nfc_baud_rate
52 str_nfc_target
53 pn53x_transceive
54 pn532_SAMConfiguration
55 pn53x_read_register
56 pn53x_write_register
0 #include "windows.h"
1
20 1 VERSIONINFO
31 FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,0
42 PRODUCTVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,0
53 FILEFLAGSMASK 0x3fL
6 #ifdef _DEBUG
7 FILEFLAGS VS_FF_DEBUG|VS_FF_PRERELEASE
8 #else
9 FILEFLAGS 0L
10 #endif
11 FILEOS VOS_NT_WINDOWS32
4 FILEFLAGS 0x0L
5 FILEOS 0x00040004L
126 FILETYPE @RC_FILE_TYPE@
137 FILESUBTYPE 0x0L
148 BEGIN
4747 # define ENOTSUP WSAEOPNOTSUPP
4848 # define ECONNABORTED WSAECONNABORTED
4949 # else
50 #ifndef _MSC_VER
5051 # define snprintf sprintf_s
52 #endif
5153 # define strdup _strdup
5254 # endif
5355
2222 SET(RC_COMMENT "${PACKAGE_NAME} example")
2323 SET(RC_INTERNAL_NAME ${source})
2424 SET(RC_ORIGINAL_NAME ${source}.exe)
25 SET(RC_FILE_TYPE VFT_APP)
25 # RC_FILE_TYPE: VFT_APP
26 SET(RC_FILE_TYPE 0x00000001L)
2627 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/../windows/${source}.rc @ONLY)
2728 LIST(APPEND TARGETS ${CMAKE_CURRENT_BINARY_DIR}/../windows/${source}.rc)
2829 ENDIF(WIN32)
44
55 # Add in the rc for version information in the dll
66 LIST(APPEND WINDOWS_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/../windows/libnfc.rc)
7 IF (NOT MINGW)
8 LIST(APPEND WINDOWS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc_msvc.def)
9 ENDIF()
710 ENDIF(WIN32)
811
912 # Library's chips
2528 ENDIF(UART_REQUIRED)
2629
2730 IF(I2C_REQUIRED)
28 IF(WIN32)
29 # Windows is not supported at the moment
31 IF(UNIX AND NOT APPLE)
32 LIST(APPEND BUSES_SOURCES buses/i2c)
33 ELSE(UNIX AND NOT APPLE)
34 # Only Linux is supported at the moment
3035 #LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/i2c)
31 MESSAGE( FATAL_ERROR "I2C not (yet) supported under Windows!" )
32 ELSE(WIN32)
33 LIST(APPEND BUSES_SOURCES buses/i2c)
34 ENDIF(WIN32)
36 MESSAGE( FATAL_ERROR "I2C is only (yet) supported in Linux!" )
37 ENDIF(UNIX AND NOT APPLE)
3538 ENDIF(I2C_REQUIRED)
3639
3740 IF(SPI_REQUIRED)
38 IF(WIN32)
39 # Windows is not supported at the moment
41 IF(UNIX AND NOT APPLE)
42 LIST(APPEND BUSES_SOURCES buses/spi)
43 ELSE(UNIX AND NOT APPLE)
44 # Only Linux is supported at the moment
4045 #LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/spi)
41 MESSAGE( FATAL_ERROR "SPI not (yet) supported under Windows!" )
42 ELSE(WIN32)
43 LIST(APPEND BUSES_SOURCES buses/spi)
44 ENDIF(WIN32)
46 MESSAGE( FATAL_ERROR "SPI is only (yet) supported in Linux!" )
47 ENDIF(UNIX AND NOT APPLE)
4548 ENDIF(SPI_REQUIRED)
4649
4750 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/buses)
6265
6366 IF(LIBNFC_LOG)
6467 IF(WIN32)
65 SET(CMAKE_C_FLAGS "-fgnu89-inline ${CMAKE_C_FLAGS}")
68 IF(MINGW)
69 SET(CMAKE_C_FLAGS "-fgnu89-inline ${CMAKE_C_FLAGS}")
70 ENDIF(MINGW)
6671 LIST(APPEND LIBRARY_SOURCES log ../contrib/win32/libnfc/log-internal)
6772 ELSE(WIN32)
6873 LIST(APPEND LIBRARY_SOURCES log log-internal)
8792 IF(WIN32)
8893 # Libraries that are windows specific
8994 TARGET_LINK_LIBRARIES(nfc wsock32)
90
91 ADD_CUSTOM_COMMAND(
92 OUTPUT libnfc.lib
93 COMMAND ${DLLTOOL} -d ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def -l ${CMAKE_CURRENT_BINARY_DIR}/libnfc.lib ${CMAKE_CURRENT_BINARY_DIR}/libnfc.dll
94 DEPENDS nfc ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def
95 )
96 ADD_CUSTOM_TARGET(win32lib ALL DEPENDS libnfc.lib)
95 IF(MINGW)
96 ADD_CUSTOM_COMMAND(
97 OUTPUT libnfc.lib
98 COMMAND ${DLLTOOL} -d ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def -l ${CMAKE_CURRENT_BINARY_DIR}/libnfc.lib ${CMAKE_CURRENT_BINARY_DIR}/libnfc.dll
99 DEPENDS nfc ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def
100 )
101 ADD_CUSTOM_TARGET(win32lib ALL DEPENDS libnfc.lib)
102 ELSE()
103 ADD_LIBRARY(win32lib ALIAS nfc)
104 ENDIF()
97105
98106 # On Windows the shared (runtime) library should be either in the same
99107 # directory as the excutables or in the path, we add it to same directory
3232 #ifndef __NFC_BUS_UART_H__
3333 # define __NFC_BUS_UART_H__
3434
35 #if !defined(_MSC_VER)
3536 # include <sys/time.h>
37 #endif
3638
3739 # include <stdio.h>
3840 # include <string.h>
12071207 // send ICLASS_ACTIVATE_ALL command - will get timeout as we don't expect response
12081208 uint8_t abtReqt[] = { 0x0a }; // iClass ACTIVATE_ALL
12091209 uint8_t abtAnticol[11];
1210 if ((res = pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), NULL, 0, timeout)) < 0) {
1210 if (pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), NULL, 0, timeout) < 0) {
12111211 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "got expected timeout on iClass activate all");
12121212 //if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout
12131213 // continue;
20632063 }
20642064 uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
20652065 uint8_t abtRxPar[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
2066 if ((ret = nfc_initiator_transceive_bits(pnd, NULL, 0, NULL, abtRx, sizeof(abtRx), abtRxPar)) < 1) {
2066 if (nfc_initiator_transceive_bits(pnd, NULL, 0, NULL, abtRx, sizeof(abtRx), abtRxPar) < 1) {
20672067 failures++;
20682068 } else {
20692069 nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true);
194194 free(key);
195195 free(value);
196196 } else {
197 free(key);
198 free(value);
197199 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Parse error on line #%d: %s", lineno, line);
198200 }
199201 }
5959 #include <sys/select.h>
6060 #include <errno.h>
6161 #include <string.h>
62
62 #ifdef _MSC_VER
63 #include <sys/types.h>
64 #endif
6365 #include <nfc/nfc.h>
6466
6567 #include "nfc-internal.h"
595597 if (timeout == USB_INFINITE_TIMEOUT) {
596598 usb_timeout = USB_TIMEOUT_PER_PASS;
597599 } else {
598 // A user-provided timeout is set, we have to cut it in multiple chunk to be able to keep an nfc_abort_command() mecanism
600 // A user-provided timeout is set, we have to cut it in multiple chunk to be able to keep an nfc_abort_command() mechanism
599601 remaining_time -= USB_TIMEOUT_PER_PASS;
600602 if (remaining_time <= 0) {
601603 pnd->last_error = NFC_ETIMEOUT;
526526 uart_close(DRIVER_DATA(pnd)->port);
527527
528528 #ifndef WIN32
529 // Release file descriptors used for abort mecanism
529 // Release file descriptors used for abort mechanism
530530 close(DRIVER_DATA(pnd)->abort_fds[0]);
531531 close(DRIVER_DATA(pnd)->abort_fds[1]);
532532 #endif
157157 }
158158
159159 #ifndef WIN32
160 // pipe-based abort mecanism
160 // pipe-based abort mechanism
161161 if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
162162 uart_close(DRIVER_DATA(pnd)->port);
163163 pn53x_data_free(pnd);
210210 uart_close(DRIVER_DATA(pnd)->port);
211211
212212 #ifndef WIN32
213 // Release file descriptors used for abort mecanism
213 // Release file descriptors used for abort mechanism
214214 close(DRIVER_DATA(pnd)->iAbortFds[0]);
215215 close(DRIVER_DATA(pnd)->iAbortFds[1]);
216216 #endif
303303 pnd->driver = &arygon_driver;
304304
305305 #ifndef WIN32
306 // pipe-based abort mecanism
306 // pipe-based abort mechanism
307307 if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
308308 uart_close(DRIVER_DATA(pnd)->port);
309309 pn53x_data_free(pnd);
44 * Copyright (C) 2019 Frank Morgner
55 * See AUTHORS file for a more comprehensive list of contributors.
66 * Additional contributors of this file:
7 *
7 * Copyright (C) 2020 Feitian Technologies
88 * This program is free software: you can redistribute it and/or modify it
99 * under the terms of the GNU Lesser General Public License as published by the
1010 * Free Software Foundation, either version 3 of the License, or (at your
7171 #include <winscard.h>
7272 #endif
7373
74 #ifdef WIN32
75 #include <windows.h>
76 #define usleep(x) Sleep((x + 999) / 1000)
77 #endif
78
7479 #define PCSC_DRIVER_NAME "pcsc"
7580
7681 #include <nfc/nfc.h>
137142 DWORD dw_rx_len = *rx_len;
138143 //in libfreefare, tx_len = 1, and it leads to 0x80100008 error, with PC/SC reader, the input tx_len at least two bytes for the SW value
139144 //so if found the reader is Feitian reader, we set to 2
140 if (dw_rx_len == 1 && is_pcsc_reader_vendor_feitian(pnd)) {
141 dw_rx_len = 2;
145 if (is_pcsc_reader_vendor_feitian(pnd))
146 {
147 if (dw_rx_len == 1)
148 {
149 dw_rx_len = 2;
150 } else {
151 dw_rx_len += 2;//in libfreefare, some data length send not include sw1 and sw2, so add it.
152 }
142153 }
143154
144155 LOG_HEX(NFC_LOG_GROUP_COM, "TX", tx, tx_len);
251262 if (pnd->last_error != NFC_SUCCESS)
252263 return pnd->last_error;
253264
254 if (resp_len < 2) {
265 if (resp_len <= 2) {
255266 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Reader doesn't support request for ATS");
256267 pnd->last_error = NFC_EDEVNOTSUPP;
257268 return pnd->last_error;
262273 return pnd->last_error;
263274 }
264275
265 //memcpy(ats, resp + 1, resp_len - 2 - 1);
266 memcpy(ats, resp + 1, resp[0] - 1);
276 memcpy(ats, resp + 1, resp_len - 2 - 1);//data expect TL and SW1SW2
267277 return resp_len - 2 - 1;
268278 }
269279
340350 if (is_pcsc_reader_vendor_feitian(pnd)) {
341351 uint8_t atqa[2];
342352 pcsc_get_atqa(pnd, atqa, sizeof(atqa));
343 //memcpy(pnt->nti.nai.abtAtqa,atqa,2);
344 pnt->nti.nai.abtAtqa[0] = atqa[1];
345 pnt->nti.nai.abtAtqa[1] = atqa[0];
353 //ATQA Coding of NXP Contactless Card ICs
354 if(atqa[0] = 0x00 || atqa[0] == 0x03)
355 {
356 memcpy(pnt->nti.nai.abtAtqa,atqa,2);
357 }else {
358 pnt->nti.nai.abtAtqa[0] = atqa[1];
359 pnt->nti.nai.abtAtqa[1] = atqa[0];
360 }
361
346362 uint8_t sak[1];
347363 pcsc_get_sak(pnd, sak, sizeof(sak));
348364 pnt->nti.nai.btSak = sak[0];
349365 uint8_t ats[256];
350366 int ats_len = pcsc_get_ats(pnd, ats, sizeof(ats));
367 ats_len = (ats_len > 0 ? ats_len : 0);//The reader may not support to get ATS
351368 memcpy(pnt->nti.nai.abtAts, ats, ats_len);
352 //memcpy(pnt->nti.nai.abtAts + ats_len, patr + 4, (uint8_t)(szatr - 5));
353 pnt->nti.nai.szAtsLen = ats_len;// + szatr - 5;
369 pnt->nti.nai.szAtsLen = ats_len;
354370 } else {
355371 /* SAK_ISO14443_4_COMPLIANT */
356372 pnt->nti.nai.btSak = 0x20;
520536 // Test if context succeeded
521537 if (!(pscc = pcsc_get_scardcontext()))
522538 goto error;
523 DRIVER_DATA(pnd)->last_error = SCardConnect(*pscc, ndd.pcsc_device_name, SCARD_SHARE_DIRECT, 0, &(DRIVER_DATA(pnd)->hCard), (void *) & (DRIVER_DATA(pnd)->ioCard.dwProtocol));
539 DRIVER_DATA(pnd)->last_error = SCardConnect(*pscc, ndd.pcsc_device_name, SCARD_SHARE_DIRECT, 0 | 1, &(DRIVER_DATA(pnd)->hCard), (void *) & (DRIVER_DATA(pnd)->ioCard.dwProtocol));
524540 if (DRIVER_DATA(pnd)->last_error != SCARD_S_SUCCESS) {
525541 // We can not connect to this device.
526542 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "PCSC connect failed");
796812 memcpy(apdu_data + 5, pbtTx + 2, szTx - 2);
797813 send_size = 5 + szTx - 2;
798814 } else if (pbtTx[0] == 0x60 || pbtTx[0] == 0x61 || pbtTx[0] == 0x1A) { //Auth command
815 //load pin first
816 {
817 apdu_data[0] = 0xFF;
818 apdu_data[1] = 0x82;
819 apdu_data[2] = 0x00;
820 apdu_data[3] = 0x01;
821 apdu_data[4] = 0x06;
822 memcpy(apdu_data + 5, pbtTx + 2, 6);
823 send_size = 11;
824 pnd->last_error = pcsc_transmit(pnd, apdu_data, send_size, resp, &resp_len);
825 memset(apdu_data, 0, sizeof(apdu_data));
826 memset(resp, 0, sizeof(resp));
827 usleep(500000);//delay 500ms
828 }
829 // then auth
799830 apdu_data[0] = 0xFF;
800831 apdu_data[1] = 0x86;
801832 apdu_data[2] = 0x00;
883914 // ignore
884915 return NFC_SUCCESS;
885916 case NP_AUTO_ISO14443_4:
917 if ((bEnable == true) || (is_pcsc_reader_vendor_feitian(pnd)))
918 return NFC_SUCCESS;
919 break;
886920 case NP_EASY_FRAMING:
887921 if ((bEnable == true) || (is_pcsc_reader_vendor_feitian(pnd)))
888922 return NFC_SUCCESS;
935969 {
936970 struct pcsc_data *data = pnd->driver_data;
937971 LPBYTE name = NULL, version = NULL, type = NULL, serial = NULL;
972 #ifdef __APPLE__
973 DWORD name_len = 0, version_len = 0,
974 type_len = 0, serial_len = 0;
975 #else
938976 DWORD name_len = SCARD_AUTOALLOCATE, version_len = SCARD_AUTOALLOCATE,
939977 type_len = SCARD_AUTOALLOCATE, serial_len = SCARD_AUTOALLOCATE;
978 #endif
940979 int res = NFC_SUCCESS;
941980 SCARDCONTEXT *pscc;
942981
135135 CHIP_DATA(pnd)->power_mode = LOWVBAT;
136136
137137 #ifndef WIN32
138 // pipe-based abort mecanism
138 // pipe-based abort mechanism
139139 if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
140140 uart_close(DRIVER_DATA(pnd)->port);
141141 pn53x_data_free(pnd);
190190 uart_close(DRIVER_DATA(pnd)->port);
191191
192192 #ifndef WIN32
193 // Release file descriptors used for abort mecanism
193 // Release file descriptors used for abort mechanism
194194 close(DRIVER_DATA(pnd)->iAbortFds[0]);
195195 close(DRIVER_DATA(pnd)->iAbortFds[1]);
196196 #endif
276276 pnd->driver = &pn532_uart_driver;
277277
278278 #ifndef WIN32
279 // pipe-based abort mecanism
279 // pipe-based abort mechanism
280280 if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
281281 uart_close(DRIVER_DATA(pnd)->port);
282282 pn53x_data_free(pnd);
4242 #include <sys/select.h>
4343 #include <errno.h>
4444 #include <string.h>
45
45 #ifdef _MSC_VER
46 #include <sys/types.h>
47 #endif
4648 #include <nfc/nfc.h>
4749
4850 #include "nfc-internal.h"
620622 if (timeout == USB_INFINITE_TIMEOUT) {
621623 usb_timeout = USB_TIMEOUT_PER_PASS;
622624 } else {
623 // A user-provided timeout is set, we have to cut it in multiple chunk to be able to keep an nfc_abort_command() mecanism
625 // A user-provided timeout is set, we have to cut it in multiple chunk to be able to keep an nfc_abort_command() mechanism
624626 remaining_time -= USB_TIMEOUT_PER_PASS;
625627 if (remaining_time <= 0) {
626628 pnd->last_error = NFC_ETIMEOUT;
816818 if (NP_ACTIVATE_FIELD == property) {
817819 /* Switch on/off LED2 and Progressive Field GPIO according to ACTIVATE_FIELD option */
818820 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Switch progressive field %s", bEnable ? "On" : "Off");
819 if ((res = pn53x_write_register(pnd, PN53X_SFR_P3, _BV(P31) | _BV(P34), bEnable ? _BV(P34) : _BV(P31))) < 0)
821 if (pn53x_write_register(pnd, PN53X_SFR_P3, _BV(P31) | _BV(P34), bEnable ? _BV(P34) : _BV(P31)) < 0)
820822 return NFC_ECHIP;
821823 }
822824 break;
3333
3434 #include <stdbool.h>
3535 #include <err.h>
36 #if !defined(_MSC_VER)
3637 # include <sys/time.h>
38 #endif
3739
3840 #include "nfc/nfc.h"
3941
564564 nfc_target *pnt)
565565 {
566566 uint8_t *abtInit = NULL;
567 uint8_t abtTmpInit[MAX(12, szInitData)];
567 uint8_t maxAbt = MAX(12, szInitData);
568 uint8_t *abtTmpInit = malloc(sizeof(uint8_t) * maxAbt);
568569 size_t szInit = 0;
569570 int res;
570 if ((res = nfc_device_validate_modulation(pnd, N_INITIATOR, &nm)) != NFC_SUCCESS)
571 return res;
571 if ((res = nfc_device_validate_modulation(pnd, N_INITIATOR, &nm)) != NFC_SUCCESS) {
572 free(abtTmpInit);
573 return res;
574 }
572575 if (szInitData == 0) {
573576 // Provide default values, if any
574577 prepare_initiator_data(nm, &abtInit, &szInit);
578 free(abtTmpInit);
575579 } else if (nm.nmt == NMT_ISO14443A) {
576580 abtInit = abtTmpInit;
577581 iso14443_cascade_uid(pbtInitData, szInitData, abtInit, &szInit);
578582 } else {
579583 abtInit = abtTmpInit;
580584 memcpy(abtInit, pbtInitData, szInitData);
585 free(abtTmpInit);
581586 szInit = szInitData;
582587 }
583
584588 HAL(initiator_select_passive_target, pnd, nm, abtInit, szInit, pnt);
589
590 free(abtTmpInit);
585591 }
586592
587593 /** @ingroup initiator
2222 SET(RC_COMMENT "${PACKAGE_NAME} utility")
2323 SET(RC_INTERNAL_NAME ${source})
2424 SET(RC_ORIGINAL_NAME ${source}.exe)
25 SET(RC_FILE_TYPE VFT_APP)
25 # RC_FILE_TYPE: VFT_APP
26 SET(RC_FILE_TYPE 0x00000001L)
2627 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/../windows/${source}.rc @ONLY)
2728 LIST(APPEND TARGETS ${CMAKE_CURRENT_BINARY_DIR}/../windows/${source}.rc)
2829 ENDIF(WIN32)
4041 LIST(APPEND TARGETS ../contrib/win32/stdlib)
4142 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32)
4243 ENDIF(${source} MATCHES "nfc-scan-device")
44 IF(${source} MATCHES "nfc-read-forum-tag3")
45 LIST(APPEND TARGETS ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/getopt.c)
46 ENDIF()
4347 ENDIF(WIN32)
4448
4549 ADD_EXECUTABLE(${source} ${TARGETS})
9696 exit(EXIT_FAILURE);
9797 }
9898
99 // Display libnfc version
100 acLibnfcVersion = nfc_version();
101 printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
102
10399 // Get commandline options
104100 for (arg = 1; arg < argc; arg++) {
105101 if (0 == strcmp(argv[arg], "-h")) {
125121 }
126122 }
127123
124 // Display libnfc version
125 if (verbose) {
126 acLibnfcVersion = nfc_version();
127 printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
128 }
129
130
128131 /* Lazy way to open an NFC device */
129132 #if 0
130133 pnd = nfc_open(context, NULL);
5353 #include <string.h>
5454 #include <ctype.h>
5555
56 #ifndef _WIN32
57 #include <fcntl.h>
58 #include <sys/stat.h>
59 #include <unistd.h>
60 #endif
61
5662 #include <nfc/nfc.h>
5763
5864 #include "mifare.h"
6975 static bool bForceKeyFile;
7076 static bool bTolerateFailures;
7177 static bool bFormatCard;
72 static bool magic2 = false;
73 static bool magic3 = false;
78 static bool dWrite = false;
7479 static bool unlocked = false;
7580 static uint8_t uiBlocks;
7681 static uint8_t keys[] = {
210215 if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp))
211216 return true;
212217
213 } else if (magic3) {
214 //If it's a One Time Write card, we're gonna authenticate with the default keys
215 memcpy(mp.mpa.abtKey, default_key, sizeof(default_key));
216
217
218 // Try to authenticate for the current sector
219 if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp)) {
220 return true;
221 }
222218 // If formatting or not using key file, try to guess the right key
223219 } else if (bFormatCard || !bUseKeyFile) {
224220 for (size_t key_index = 0; key_index < num_keys; key_index++) {
241237 }
242238
243239 static bool
244 unlock_card(void)
240 unlock_card(bool write)
245241 {
246242 // Configure the CRC
247243 if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) {
259255 // now send unlock
260256 if (!transmit_bits(abtUnlock1, 7)) {
261257 printf("Warning: Unlock command [1/2]: failed / not acknowledged.\n");
258 dWrite = true;
259 if (write) {
260 printf("Trying to rewrite block 0 on a direct write tag.\n");
261 }
262262 } else {
263263 if (transmit_bytes(abtUnlock2, 1)) {
264264 printf("Card unlocked\n");
269269 }
270270
271271 // reset reader
272 if (!unlocked) {
273 if (nfc_initiator_select_passive_target(pnd, nmMifare, nt.nti.nai.abtUid, nt.nti.nai.szUidLen, NULL) <= 0) {
274 printf("Error: tag was removed\n");
275 nfc_close(pnd);
276 nfc_exit(context);
277 exit(EXIT_FAILURE);
278 }
279 return true;
280 }
272281 // Configure the CRC
273282 if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true) < 0) {
274283 nfc_perror(pnd, "nfc_device_set_property_bool");
315324 }
316325
317326 static bool
318 read_card(int read_unlocked)
327 read_card(bool read_unlocked)
319328 {
320329 int32_t iBlock;
321330 bool bFailure = false;
322331 uint32_t uiReadBlocks = 0;
323332
324333 if (read_unlocked) {
334 unlock_card(false);
325335 //If the user is attempting an unlocked read, but has a direct-write type magic card, they don't
326336 //need to use the R mode. We'll trigger a warning and let them proceed.
327 if (magic2) {
328 printf("Note: This card does not require an unlocked read (R) \n");
337 if (dWrite) {
338 printf("Note: This card can't do an unlocked read (R) \n");
329339 read_unlocked = 0;
330 } else {
331 //If User has requested an unlocked read, but we're unable to unlock the card, we'll error out.
332 if (!unlock_card()) {
333 return false;
334 }
335340 }
336341 }
337342
361366 if (read_unlocked) {
362367 memcpy(mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, sizeof(mtDump.amb[iBlock].mbd.abtData));
363368 } else {
364 //If we're using a One Time Write ('Magic 3') Badge - we'll use default keys + ACL
365 if (magic3) {
366 memcpy(mtDump.amb[iBlock].mbt.abtKeyA, default_key, sizeof(default_key));
367 memcpy(mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpt.abtAccessBits, sizeof(mtDump.amb[iBlock].mbt.abtAccessBits));
368 memcpy(mtDump.amb[iBlock].mbt.abtKeyB, default_key, sizeof(default_key));
369 } else {
370 // Copy the keys over from our key dump and store the retrieved access bits
371 memcpy(mtDump.amb[iBlock].mbt.abtKeyA, mtKeys.amb[iBlock].mbt.abtKeyA, sizeof(mtDump.amb[iBlock].mbt.abtKeyA));
372 memcpy(mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpt.abtAccessBits, sizeof(mtDump.amb[iBlock].mbt.abtAccessBits));
373 memcpy(mtDump.amb[iBlock].mbt.abtKeyB, mtKeys.amb[iBlock].mbt.abtKeyB, sizeof(mtDump.amb[iBlock].mbt.abtKeyB));
369 // Copy the keys over from our key dump and store the retrieved access bits
370 memcpy(mtDump.amb[iBlock].mbt.abtKeyA, mtKeys.amb[iBlock].mbt.abtKeyA, sizeof(mtDump.amb[iBlock].mbt.abtKeyA));
371 memcpy(mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpt.abtAccessBits, sizeof(mtDump.amb[iBlock].mbt.abtAccessBits));
372 memcpy(mtDump.amb[iBlock].mbt.abtKeyB, mtKeys.amb[iBlock].mbt.abtKeyB, sizeof(mtDump.amb[iBlock].mbt.abtKeyB));
374373 }
375 }
376374 } else {
377375 printf("!\nfailed to read trailer block 0x%02x\n", iBlock);
378376 bFailure = true;
402400 }
403401
404402 static bool
405 write_card(int write_block_zero)
403 write_card(bool write_block_zero)
406404 {
407405 uint32_t uiBlock;
408406 bool bFailure = false;
410408
411409 //Determine if we have to unlock the card
412410 if (write_block_zero) {
413 //If the user is attempting an unlocked write, but has a direct-write type magic card, they don't
414 //need to use the W mode. We'll trigger a warning and let them proceed.
415 if (magic2) {
416 printf("Note: This card does not require an unlocked write (W) \n");
417 write_block_zero = 0;
418 } else {
419 //If User has requested an unlocked write, but we're unable to unlock the card, we'll error out.
420 if (!unlock_card()) {
421 return false;
422 }
423 }
424 }
425
426 printf("Writing %d blocks |", uiBlocks + 1);
427 // Completely write the card, end to start, but skipping block 0
428 for (uiBlock = 4; uiBlock <= uiBlocks; uiBlock++) {
411 unlock_card(true);
412 }
413
414 printf("Writing %d blocks |", uiBlocks + write_block_zero);
415 // Completely write the card, but skipping block 0 if we don't need to write on it
416 for (uiBlock = 0; uiBlock <= uiBlocks; uiBlock++) {
417 //Determine if we have to write block 0
418 if (!write_block_zero && uiBlock == 0) {
419 continue;
420 }
429421 // Authenticate everytime we reach the first sector of a new block
430 if (is_first_block(uiBlock)) {
422 if (uiBlock == 1 || is_first_block(uiBlock)) {
431423 if (bFailure) {
432424 // When a failure occured we need to redo the anti-collision
433425 if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
441433
442434 // Try to authenticate for the current sector
443435 // If we are are writing to a chinese magic card, we've already unlocked
444 // If we're writing to a One Time Write card, we need to authenticate
436 // If we're writing to a direct write card, we need to authenticate
445437 // If we're writing something else, we'll need to authenticate
446 if ((write_block_zero && magic3) || !write_block_zero) {
438 if ((write_block_zero && dWrite) || !write_block_zero) {
447439 if (!authenticate(uiBlock) && !bTolerateFailures) {
448440 printf("!\nError: authentication failed for block %02x\n", uiBlock);
449441 return false;
450442 }
451443 }
444 }
452445
453446 if (is_trailer_block(uiBlock)) {
454447 if (bFormatCard) {
469462 bFailure = true;
470463 }
471464 } else {
472 // The first block 0x00 is read only, skip this
473 if (uiBlock == 0 && !write_block_zero && !magic2)
474 continue;
475
476465 // Make sure a earlier write did not fail
477466 if (!bFailure) {
478467 // Try to write the data block
483472 memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, sizeof(mp.mpd.abtData));
484473 // do not write a block 0 with incorrect BCC - card will be made invalid!
485474 if (uiBlock == 0) {
486 if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !magic2) {
475 if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00) {
487476 printf("!\nError: incorrect BCC in MFD file!\n");
488477 printf("Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]);
489478 return false;
493482 bFailure = true;
494483 printf("Failure to write to data block %i\n", uiBlock);
495484 }
496
485 if (uiBlock == 0 && dWrite) {
486 if (nfc_initiator_init(pnd) < 0) {
487 nfc_perror(pnd, "nfc_initiator_init");
488 nfc_close(pnd);
489 nfc_exit(context);
490 exit(EXIT_FAILURE);
491 };
492 if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
493 printf("!\nError: tag was removed\n");
494 return false;
495 }
496 }
497497 } else {
498498 printf("Failure during write process.\n");
499499 }
500500 }
501 }
501 //}
502502 // Show if the write went well for each block
503503 print_success_or_failure(bFailure, &uiWriteBlocks);
504504 if ((! bTolerateFailures) && bFailure)
505505 return false;
506 }
507
508 //Write Block 0 if necessary
509 if (write_block_zero || magic2 || magic3) {
510 for (uiBlock = 0; uiBlock < 4; uiBlock++) {
511
512 // The first block 0x00 is read only, skip this
513 if (uiBlock == 0) {
514 //If the card is not magic, we're gonna skip over
515 if (write_block_zero || magic2 || magic3) {
516 //NOP
517 } else {
518 continue;
519 }
520 }
521
522 if (is_first_block(uiBlock)) {
523 if (bFailure) {
524 // When a failure occured we need to redo the anti-collision
525 if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
526 printf("!\nError: tag was removed\n");
527 return false;
528 }
529 bFailure = false;
530 }
531
532 fflush(stdout);
533 // Try to authenticate for the current sector
534 // If we are are writing to a chinese magic card, we've already unlocked
535 // If we're writing to a One Time Write, we need to authenticate
536 // If we're writing something else, we'll need to authenticate
537 if ((write_block_zero && magic3) || !write_block_zero) {
538 if (!authenticate(uiBlock) && !bTolerateFailures) {
539 printf("!\nError: authentication failed for block %02x\n", uiBlock);
540 return false;
541 }
542 }
543 }
544
545 // Make sure a earlier write did not fail
546 if (!bFailure) {
547 // Try to write the data block
548 if (bFormatCard && uiBlock)
549 memset(mp.mpd.abtData, 0x00, sizeof(mp.mpd.abtData));
550 else
551 memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, sizeof(mp.mpd.abtData));
552 // do not write a block 0 with incorrect BCC - card will be made invalid!
553 if (uiBlock == 0) {
554 if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !magic2) {
555 printf("!\nError: incorrect BCC in MFD file!\n");
556 printf("Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]);
557 return false;
558 }
559 }
560 if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp)) {
561 bFailure = true;
562 printf("Failure to write to data block %i\n", uiBlock);
563 }
564
565 } else {
566 printf("Failure during write process.\n");
567 }
568
569 // Show if the write went well for each block
570 print_success_or_failure(bFailure, &uiWriteBlocks);
571 if ((! bTolerateFailures) && bFailure)
572 return false;
573
574 }
575
576506 }
577507
578508 printf("|\n");
592522 print_usage(const char *pcProgramName)
593523 {
594524 printf("Usage: ");
525 #ifndef _WIN32
526 printf("%s f|r|R|w|W a|b u|U<01ab23cd> <dump.mfd> [<keys.mfd> [f] [v]]\n", pcProgramName);
527 #else
595528 printf("%s f|r|R|w|W a|b u|U<01ab23cd> <dump.mfd> [<keys.mfd> [f]]\n", pcProgramName);
596 printf(" f|r|R|w|W - Perform format (f) or read from (r) or unlocked read from (R) or write to (w) or unlocked write to (W) card\n");
529 #endif
530 printf(" f|r|R|w|W - Perform format (f) or read from (r) or unlocked read from (R) or write to (w) or block 0 write to (W) card\n");
597531 printf(" *** format will reset all keys to FFFFFFFFFFFF and all data to 00 and all ACLs to default\n");
598532 printf(" *** unlocked read does not require authentication and will reveal A and B keys\n");
599 printf(" *** note that unlocked write will attempt to overwrite block 0 including UID\n");
600 printf(" *** unlocking only works with special Mifare 1K cards (Chinese clones)\n");
533 printf(" *** note that block 0 write will attempt to overwrite block 0 including UID\n");
534 printf(" *** block 0 write only works with special Mifare cards (Chinese clones)\n");
601535 printf(" a|A|b|B - Use A or B keys for action; Halt on errors (a|b) or tolerate errors (A|B)\n");
602536 printf(" u|U - Use any (u) uid or supply a uid specifically as U01ab23cd.\n");
603537 printf(" <dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
604538 printf(" <keys.mfd> - MiFare Dump (MFD) that contain the keys (optional)\n");
605539 printf(" f - Force using the keyfile even if UID does not match (optional)\n");
606
540 #ifndef _WIN32
541 printf(" v - Sends libnfc log output to console (optional)\n");
542 #endif
607543 printf("Examples: \n\n");
608544 printf(" Read card to file, using key A:\n\n");
609545 printf(" %s r a u mycard.mfd\n\n", pcProgramName);
619555 }
620556
621557
622 static bool is_directwrite(void)
623 {
624 printf("Checking if Badge is DirectWrite...\n");
625
626 // Set default keys
627 memcpy(mtDump.amb[0].mbt.abtKeyA, default_key, sizeof(default_key));
628 memcpy(mtDump.amb[0].mbt.abtAccessBits, default_acl, sizeof(mp.mpt.abtAccessBits));
629 memcpy(mtDump.amb[0].mbt.abtKeyB, default_key, sizeof(default_key));
630
631 // Temporarly override bUseKeyFile
632 bool orig_bUseKeyFile = bUseKeyFile;
633 bUseKeyFile = false;
634 // Try to authenticate for the current sector
635 if (!authenticate(0)) {
636 printf("!\nError: authentication failed for block 0x%02x\n", 0);
637 bUseKeyFile = orig_bUseKeyFile;
638 return false;
639 }
640 // restore bUseKeyFile
641 bUseKeyFile = orig_bUseKeyFile;
642
643 // Try to read block 0
644 uint8_t original_b0[16];
645 if (nfc_initiator_mifare_cmd(pnd, MC_READ, 0, &mp)) {
646 memcpy(original_b0, mp.mpd.abtData, sizeof(mp.mpd.abtData));
647 printf(" Original Block 0: ");
648 for (int i = 0; i < 16; i++) {
649 printf("%02x", original_b0[i]);
650 }
651 printf("\n");
652 printf(" Original UID: %02x%02x%02x%02x\n",
653 original_b0[0], original_b0[1], original_b0[2], original_b0[3]);
654 } else {
655 printf("!\nError: unable to read block 0x%02x\n", 0);
656 return false;
657 }
658
659 printf(" Attempt to write Block 0 ...\n");
660 memcpy(mp.mpd.abtData, original_b0, sizeof(original_b0));
661 if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, 0, &mp)) {
662 printf("Failure to write to data block %i\n", 0);
663 return false;
664 }
665 printf(" Block 0 written successfully\n");
666
667 return true;
668 }
669
670558 int
671559 main(int argc, const char *argv[])
672560 {
675563 uint8_t _tag_uid[4];
676564 uint8_t *tag_uid = _tag_uid;
677565
678 int unlock = 0;
566 bool unlock = false;
679567
680568 if (argc < 2) {
681569 print_usage(argv[0]);
690578 if (strcmp(command, "r") == 0 || strcmp(command, "R") == 0) {
691579 atAction = ACTION_READ;
692580 if (strcmp(command, "R") == 0)
693 unlock = 1;
581 unlock = true;
694582 bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
695583 bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
696 bUseKeyFile = (argc > 5);
584 bUseKeyFile = (argc > 5) && strcmp(argv[5], "v");
697585 bForceKeyFile = ((argc > 6) && (strcmp((char *)argv[6], "f") == 0));
698586 } else if (strcmp(command, "w") == 0 || strcmp(command, "W") == 0 || strcmp(command, "f") == 0) {
699587 atAction = ACTION_WRITE;
700588 if (strcmp(command, "W") == 0)
701 unlock = 1;
589 unlock = true;
702590 bFormatCard = (strcmp(command, "f") == 0);
703591 bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
704592 bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
705 bUseKeyFile = (argc > 5);
593 bUseKeyFile = (argc > 5) && strcmp(argv[5], "v");
706594 bForceKeyFile = ((argc > 6) && (strcmp((char *)argv[6], "f") == 0));
707595 }
708596 if (argv[3][0] == 'U') {
724612 tag_uid = NULL;
725613 }
726614
615 #ifndef _WIN32
616 // Send noise from lib to /dev/null
617 bool verbose = false;
618 if (argv[7]) {
619 if (strcmp(argv[7], "v") == 0) verbose = true;
620 } else {
621 if ((strcmp(argv[6], "v")) || (strcmp(argv[5], "v")) == 0) verbose = true;
622 }
623 if (!verbose) {
624 int fd = open("/dev/null", O_WRONLY);
625 dup2(fd, 2);
626 close(fd);
627 }
628 #endif
629
727630 if (atAction == ACTION_USAGE) {
728631 print_usage(argv[0]);
729632 exit(EXIT_FAILURE);
763666 exit(EXIT_FAILURE);
764667 };
765668
669 // Drop the field for a while, so can be reset
670 if (nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, true) < 0) {
671 nfc_perror(pnd, "nfc_device_set_property_bool activate field");
672 nfc_close(pnd);
673 nfc_exit(context);
674 exit(EXIT_FAILURE);
675 }
676
766677 // Let the reader only try once to find a tag
767678 if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
768679 nfc_perror(pnd, "nfc_device_set_property_bool");
778689 exit(EXIT_FAILURE);
779690 }
780691
692 // Configure the CRC and Parity settings
693 if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true) < 0) {
694 nfc_perror(pnd, "nfc_device_set_property_bool crc");
695 nfc_close(pnd);
696 nfc_exit(context);
697 exit(EXIT_FAILURE);
698 }
699 if (nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true) < 0) {
700 nfc_perror(pnd, "nfc_device_set_property_bool parity");
701 nfc_close(pnd);
702 nfc_exit(context);
703 exit(EXIT_FAILURE);
704 }
705
781706 printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));
782707
783708 // Try to find a MIFARE Classic tag
784709 int tags;
785
786710 tags = nfc_initiator_select_passive_target(pnd, nmMifare, tag_uid, tag_uid == NULL ? 0 : 4, &nt);
787711 if (tags <= 0) {
788712 printf("Error: no tag was found\n");
791715 exit(EXIT_FAILURE);
792716 }
793717 // Test if we are dealing with a MIFARE compatible tag
794 if ((nt.nti.nai.btSak & 0x08) == 0) {
718 if (((nt.nti.nai.btSak & 0x08) == 0) && (nt.nti.nai.btSak != 0x01)) {
719 // if ((nt.nti.nai.btSak & 0x08) == 0) {
795720 printf("Warning: tag is probably not a MFC!\n");
796721 }
797722
838763 // MIFARE Plus 2K
839764 uiBlocks = 0x7f;
840765 }
841 // Chinese magic emulation card, ATS=0978009102:dabc1910
842 if ((res == 9) && (abtRx[5] == 0xda) && (abtRx[6] == 0xbc)
843 && (abtRx[7] == 0x19) && (abtRx[8] == 0x10)) {
844 magic2 = true;
845 }
846766 } else
847767 printf("RATS support: no\n");
848768 printf("Guessing size: seems to be a %lu-byte card\n", (unsigned long)((uiBlocks + 1) * sizeof(mifare_classic_block)));
849
850 //If size is 4k check for direct-write card
851 if (uiBlocks == 0xff) {
852 if (is_directwrite()) {
853 printf("Card is DirectWrite\n");
854 magic3 = true;
855 unlock = 0;
856 } else {
857 printf("Card is not DirectWrite\n");
858 }
859 }
860
861 //Check to see if we have a One Time Write badge (magic3)
862 if (pbtUID[0] == 0xaa && pbtUID[1] == 0x55 &&
863 pbtUID[2] == 0xc3 && pbtUID[3] == 0x96) {
864 printf("Card appears to be a One Time Write Card..\n");
865 magic3 = true;
866 unlock = 0;
867 }
868
869769
870770 if (bUseKeyFile) {
871771 FILE *pfKeys = fopen(argv[5], "rb");
921821 }
922822 printf("Done.\n");
923823 fclose(pfDump);
824 } else {
825 nfc_close(pnd);
826 nfc_exit(context);
827 exit(EXIT_FAILURE);
924828 }
925829 } else if (atAction == ACTION_WRITE) {
926 write_card(unlock);
830 if (!write_card(unlock)) {
831 nfc_close(pnd);
832 nfc_exit(context);
833 exit(EXIT_FAILURE);
834 }
927835 }
928836
929837 nfc_close(pnd);
6161
6262 #include "nfc-utils.h"
6363
64 #if defined(WIN32) && defined(__GNUC__) /* mingw compiler */
64 #if defined(WIN32) /* mingw compiler */
6565 #include <getopt.h>
6666 #endif
6767