ifd-gempc-1.0.7/0000755000175000017500000000000011740401711013644 5ustar rousseaurousseauifd-gempc-1.0.7/MANIFEST0000644000175000017500000000203111146613715015002 0ustar rousseaurousseauChangelog check common/COPYING.BSD common/COPYING.GPL common/.dependencies common/GCCmds.c common/GCCmds.h common/GCdebug.c common/GCdebug.h common/GCTransport.h common/GCUtils.c common/GCUtils.h common/GemCore.h common/gempc_ifdhandler.h common/ifdhandler.c common/Makefile create_distrib.sh GemPC410/Config.h GemPC410/COPYING.GPL GemPC410/.dependencies GemPC410/gbpserial.c GemPC410/gbpserial.h GemPC410/GCGBPTransport.c GemPC410/GemPC410Utils.c GemPC410/GemPC410Utils.h GemPC410/main.c GemPC410/Makefile GemPC410/resetGemPC410.c GemPC410/TODO.txt GemPC430/Config.h GemPC430/COPYING GemPC430/.dependencies GemPC430/GCUSBTransport.c GemPC430/GemPC430Utils.c GemPC430/GemPC430Utils.h GemPC430/Info.plist GemPC430/libusb_wrap.c GemPC430/libusb_wrap.h GemPC430/Makefile GemPC430/TODO.txt GemPC430/usbserial.h GemPC430/usbserial_mosx.c MacOSXbuild/debuglog.h MacOSXbuild/ifd-GemPC430/English.lproj/InfoPlist.strings MacOSXbuild/ifd-GemPC430/ifd-GemPC430.xcodeproj/project.pbxproj MacOSXbuild/ifdhandler.h Makefile MANIFEST README README.410 README.430 ifd-gempc-1.0.7/README.4300000644000175000017500000000254710561621046015046 0ustar rousseaurousseauGemplus GemPC 430 reader driver README ====================================== Compilation under Unix (Linux, xBSD) except MacOSX ================================================== The libgempc430 driver uses a library to access USB devices. This library is libusb [1] and is available for Linux, NetBSD, FreeBSD, OpenBSD, Darwin, MacOSX. The MacOSX driver DO NOT use this library (even if it could). You need to install this library and in particular its usb.h file to compile the driver under GNU/Linux. [1] http://libusb.sourceforge.net/ USB support under Linux ======================= In order to use the USB ports your kernel needs to support usbdevfs. You should have the following results: $ grep usb /proc/devices 180 usb $ grep usb /proc/filesystems nodev usbdevfs nodev usbfs If it is not the case consult [2]. You may have to recompile your kernel. [2] http://www.linux-usb.org/ /proc/bus/usb/ directory under Linux ==================================== The driver accesses directly the devices in /proc/bus/usb/*. So this directory /proc/bus/usb/ MUST exists. You have at least two solutions to create this virtual directory: - use the hotplug package from http://linux-hotplug.sourceforge.net/ - add a line to your /etc/fstab, see [3] [3] /usr/src/linux/Documentation/usb/proc_usb_info.txt $Id: README.430,v 1.4 2003-04-12 20:18:51 rousseau Exp $ ifd-gempc-1.0.7/README0000644000175000017500000004106211740401707014534 0ustar rousseaurousseauGemplus GemPC 410 and GemPC 430 IFD Handler =========================================== This package provides the source code for the GemPC 410 (serial) and GemPC 430 (usb) smart card familly readers PC/SC ifd handler. Both readers use a GemCore chip and the same set of commands. Only the low level transport layer is different. See README.410 for GemPC410 specific comments. See README.430 for GemPC430 specific comments. Authors: ======== - David Corcoran for the original headers and empty ifdhandler.c file - Jean-Luc Giraud for the main part of GemPC430/ and half of common/ - Ludovic Rousseau for the main part of GemPC410/ and half of common/ Supported readers: ================== - GemPC 410 . normal GemPC 410 (GemCore-R1.21-GM) . IBM 410p (v1.21) . GemPC 410-SL (GemCore-R1.21-GM) - GemPC 412 . GCR412 FirstUSA (GemCore-R1.21-GM) - GemPC 413 . EMV complient (GemCore-R1.32-GK) - GemPC 415 . VISA and American Express 415 (unkown) - GemPC 430 . normal GemPC 430 (GemUsb-R1.04-GM) - GemPC 432 . target.com (GemUsb-R1.04-WM) - GemPC 435 . American Express Blue Card reader (GemUsb-R1.04-A) The number in () is the GemCore version as seen in the logs generated by the driver. Like in "(GemPC430) OS string: GemUsb-R1.04-GM" or "(GemPC410) OS string: GemCore-R1.21-I" Unsupported GemCore based readers: ================================== - GCR400 Very old version of the GemPC410. - GCR410 Old version of the GemPC410. This reader uses a GemCore version 1.118 or 1.10. With this firmware the case 4 commands (both input and output data) will not work. Licences: ========= The files in GemPC410/ are under GNU General Public Licence. The files in GemPC430/ are under a BSD-like licence (except main.c which is under GPL but is not needed to build the driver). The files in common/ are under a double licence BSD-like and GNU General Public Licence. except the files ifdhandler.c, ifdhandler.h and pcscdefines.h which are originally written by David Corcoran and are under the BSD-like licence. That means that the GemPC 410 driver is under GNU General Public Licence, and that the GemPC 430 driver is the BSD-like licence or the GNU General Public Licence at your choice. Supported pcsc-lite versions ============================ pcsc-lite 1.1.2beta4 and later You can get the latest pcsc-lite version from http://linuxnet.com/middle.html or from http://pcsclite.alioth.debian.org/ Get pcsc-lite higher than 1.2.0 if you want to use /etc/reader.conf DEVICENAME fields managed by the new API IFDHCreateChannelByName() History: ======== 1.0.7 - 8 April 2012, Ludovic Rousseau - add GemPC430/50-pcscd-ifd-gempc.rules udev file - Use CFLAGS and LDFLAGS in Makefile (Debian bug #667931) 1.0.6 - 16 June 2010, Ludovic Rousseau - fix an error in opening a serial port Thanks to Joerg Hartenberger for the patch - fix spelling error 1.0.5 - 12 April 2009, Ludovic Rousseau - correctly manage LDFLAGS Thanks to Arfrever Frehtes Taifersar Arahesis for the patch - correct compilation warnings 1.0.4 - 15 October 2008, Ludovic Rousseau - Allow the header to be read in several calls Previously, if the header was not read in a single read() calls, there was an error. This is an issue because some commands return the two first bytes, then a small pause, then the rest of the header ... At least this happens on a gci410emv connected thru an usb adapter ... Now it works fine. Patch from Sylvain Munaut - Fix powerup sequence when switching to ISO mode If somehow the reader/card was in EMV mode, we need to switch it to ISO. This was done but the final attemp to powerup tried to power it up in EMV mode ... most likely a typo. Patch from Sylvain Munaut 1.0.3 - 14 August 2007, Ludovic Rousseau - correct a big bug unnoticed for many years and declared on PowerPC with gcc 4.x (Debian bug #428323) - do not strip the library so we have debug symbols if needed. strip should be called by the package build process (if needed) 1.0.2 - 29 June 2007, Ludovic Rousseau - correctly handle empty response from the GemPC410 reader 1.0.1 - 9 February 2006, Ludovic Rousseau - remove a useless "POUET" debug message - allow compilation with pcsc-lite-1.2.9-beta10. The check script was buggy for beta > 9 - fix some compilation warnings with gcc 4.0 1.0.0 - 17 June 2005, Ludovic Rousseau - use new pcscd log function with dynamic level - use `pkg-config libpcsclite --variable=usbdropdir` to know where to install the driver 0.9.3 - 8 August 2004, Ludovic Rousseau - maintainance release to make it compile using gcc-3.4 0.9.2 - 25 July 2004, Ludovic Rousseau - use the header files provided by pcsc-lite 1.2.9-beta - use pkg-config to know the where to find the pcsc-lite include files - minium pcsc-lite version is 1.2.9-beta5 0.9.1 - 27 February 2004, Ludovic Rousseau - add a compilation flag AUTOMATIC_PPS to activate automatic PPS negociation by the reader firmware. I received many bug reports with some cards. The card works until some APDU returns a "invalid procedure byte" error. By default the automatic PPS negociation is now NOT performed. Uncomment a line in GemPC4?0/Config.h to revert to the previous behavior and choose speed versus safety - GemPC430/libusb_wrap.c: use pcsc-lite new IFDHCreateChannelByName() scheme: usb:vendor/product In 0.9.0 the driver failed when used with a CVS version of pcsc-lite. Thanks to Dr Russel Winder for the bug report - common/GCCmds.h: the GemCore error message now contains the file, function and line number of the command with error and not of the error printing function - add two GemCore error code descriptions: 0x15 and 0xE4 0.9.0 - 22 January 2004, Ludovic Rousseau - add support of IFDHCreateChannelByName() (from pcsc-lite > 1.2.0) - GemPC430/libusb_wrap.c: reset the reader in case of timeout on write (reader freeze?). Thanks to Patrick Valsecchi for the patch. - use asymetric timeout for USB read and write. The reader/card may be busy when we read (long timeout) but should be OK when we write (short timeout) 0.8.2 - 22 Octobre 2003, Ludovic Rousseau - Remove support for multi slot. The code was never used and is now broken under revent pcsc-lite versions. The error under pcsc-lite is: readerfactory.c:1391 RFInitializeReader: Attempting startup of GemPC430 0 0. readerfactory.c:1133 RFBindFunctions: Loading IFD Handler 2.0 ifdhandler.c:87 (GemPC43x) Entering IFDHCreateChannel (lun: 0) GCCmds.c:394 (GemPC43x) GCCmdSetMode GCCmds.c:319 (GemPC43x) GCCmdGetOSVersion GemPC430Utils.c:51 (GemPC43x) OS string: GemUsb-R1.04-GM ifdhandler.c:158 (GemPC43x) entering IFDHGetCapabilities (lun: 0) ifdhandler.c:158 (GemPC43x) entering IFDHGetCapabilities (lun: 0) readerfactory.c:1391 RFInitializeReader: Attempting startup of GemPC430 0 1. readerfactory.c:925 RFLoadReader: Warning library pointer not NULL readerfactory.c:1133 RFBindFunctions: Loading IFD Handler 2.0 ifdhandler.c:87 (GemPC43x) Entering IFDHCreateChannel (lun: 1) libusb_wrap.c:106 (GemPC43x) USB driver with lun 1 already in use GemPC430Utils.c:30 (GemPC43x) OpenUSB failed ifdhandler.c:102 (GemPC43x) OpenReader failed readerfactory.c:1428 RFInitializeReader: Open Port 200000 Failed readerfactory.c:423 RFAddReader: GemPC430 init failed. hotplug_libusb.c:344 Adding USB device: 002:002 readerfactory.c:119 RFAddReader: Duplicate reader found. hotplug_libusb.c:344 Adding USB device: 002:002 readerfactory.c:119 RFAddReader: Duplicate reader found. [...] The reader told pcsc-lite that it supported two slots and pcsc-lite wanted to start two readers (one for each slot). - add support for 7 new GemCore error codes - check: Explain how to tell check to look elsewhere than just /usr/ and /usr/local/ 0.8.1 - 2 Septembre 2003, Ludovic Rousseau - ./check: uses paths defined in the Makefiles (if libusb is not installed in /usr or /usr/local) - common/GCCmds.c: add support of GemCore "Parity error during exchange" - GemPC410/devfs/libgempc410.devfsd.conf: use $devpath instead of $devname otherwise we have /dev/pcsc/1 -> tts/0 instead of /dev/pcsc/1 -> /dev/tts/0 - GemPC430/Info.plist: use new style - common/ifdhandler.c: FDHGetCapabilities() add support of tag TAG_IFD_SLOTS_NUMBER. All the readers I have/know have only one slot so this does not bring any new real functionnality. - Makefiles: do not exit with failure if makedepend(1) does not exist - update build and distclean rules. 0.8.0 - 12 April 2003, Ludovic Rousseau - Add support for GemPC 413 reader. That reader uses GemCore 2000 and is EMV complient (different powerup sequence). - Add support for driver aliasing for USB drivers. Allows to connect different readers like a 430 and a 432 at the same time. You will need pcsc-lite-1.1.2beta4 for that. - change USB timeout from 10 to 60 seconds. - check: do not use /usr/local/include by default since cpp will warning on some systems (recent RedHat systems). - optimize Makefile to limit restarting unnecessary check and building. - driver filename for USB is now versioned (ie libGemPC430.so.0.8.0). 0.7.4 - 20 November 2002, Ludovic Rousseau - add comment on how to compile the USB driver (install libusb, etc.) - add the ./check script (MacOS X is not concerned here). Many users add problems with a "undefined symbol: debug_msg" error when starting pcscd. It will now NOT be possible to compile the drivers unless the _minimum_ versions of libusb and pcsc-lite are installed. 0.7.3 - 18 October 2002, Ludovic Rousseau - The GemPC430 driver under Linux now support hotplug. With the previous versions the reader(s) needed to be plugged _before_ pcscd is started. 0.7.2 - 15 October 2002, Ludovic Rousseau - very very small modification. The previous compilation problem was not corrected. 0.7.1 - 15 October 2002, Ludovic Rousseau - very small modification to ease or allow compilation on some platforms (all 11 Debian supported platforms except i386) 0.7.0 - 13 October 2002, Jean-Luc Giraud, Ludovic Rousseau - the drivers are now shipped with low level debug messages OFF - do not depend on makedepend(1) anymore. Use it if present only. - GemPC410: - retry the last command if GBP returns a wrong first byte (NAD). This will help some GemPC410 to work. Before pcscd had to be started a second time. - add support for GemCore Repeat requests - GemPC410/devfs/ contains configuration files for devfs Linux systems - README.430: add a note about /proc/bus/usb/ directory under Linux - usbserial_mosx.c: - better stability and multiple reader support - the productId is now read from the Info.plist. This allow to support readers like the 432 and 435 without recompiling the library - libusb_wrap.[c|h] new files to use libusb under Linux and other systems supported by libusb. The USB driver _should_ work under FreeBSD and OpenBSD but in fact does not. 0.6.5 - 16 August 2002, Ludovic Rousseau - update README with the new readers supported (412, 415, 432, 435) - we now use the debug facilities from pcscd. see "Supported pcsc-lite" section - GemPC410/gbpserial.c: the serial initialisation should work - GemPC430/usbserial_linux.c: support for 432 and 435 readers 0.6.4 - 21 May 2002, Ludovic Rousseau - common/GCCmds.c: perform a powerup without PPS managment if the powerup with PPS managment failed - */Makefile: correctly remove .dependencies files - change sys_errlist[errno] to strerror(errno) to be (more) ready for the Hurd 0.6.3 - 9 May 2002, Ludovic Rousseau - README.410: Add info on /dev/pcsc/ for OpenBSD and FreeBSD - Case1 APDUs are converted in ISO IN commands (with length=0) instead of ISO OUT commands - some code cleanup 0.6.2 - 01 Apr 2002, Ludovic Rousseau, Jean-Luc Giraud - Add support for TAG_IFD_SIMULTANEOUS_ACCESS in IFDHGetCapabilities - Restore automatic PPS management compatible with Cyberflex - GemPC430/usbserial_mosx.c: fixes for multi-reader support - GemPC410/gbpserial.c: complete reimplementation of serial port configuration 0.6.1 - 11 Mar 2002, Ludovic Rousseau - GemPC410/gbpserial.c: . modified again the port BAUDS setting during open(). 0.6.0 - 7 Mar 2002, Ludovic Rousseau - GemPC410/gbpserial.c: . modified the port BAUDS setting during open(). . Changed the timeout delay from 2 to 10 seconds - common/ifdhandler.c: IFDHTransmitToICC: now manages case 1 APDU (only CLA, INS, P1, P2) as an outgoing APDU (CLA, INS, P1, P2, 0) - add a debug level: PERIODIC for... periodic calls. Do not define DEBUG_LEVEL_PERIODIC in GemPC4?0/Config.h if you don't want to see periodic logs from GCCmdCardStatus(), IFDHSetCapabilities() and IFDHICCPresence() - add a note about support of the IBM-410p reader. 0.5.10 - 3 Mar 2002, Ludovic Rousseau, Jean-Luc Giraud - fix bug with some kind of Cyberflex Access cards: . disable PPS management . the reader stays at 9600 bauds in all cases - fix bug when more than 252 output bytes are expected and less than that are available (which is the case when the card sends an error) - modify install: rule to include release version number in filename, create symlinks, remove execution right on the .so lib - README.410: Add a script to create the /dev/pcsc/? links - GemPC430/GemPC430Utils.c, GemPC410/GemPC410Utils.c, common/GCCmds.c: guarantee that the os_string is \0 terminated - GemPC410/resetGemPC410.c, GemPC410/gbpserial.c: use cfgetospeed()/cfsetospeed() instead of accessing directly the termios structure . the driver now works under OpenBSD - common/ifdhandler.c: also log APDU results 0.5.9 - 30 Nov 2001, Jean-Luc Giraud - fix bug in GCUtils.c/gemcore_ISO_EXCHANGE_processing() - added ProjectBuilder folder for MacOS X 0.5.8 - 27 Nov 2001, Ludovic Rousseau - MANIFEST: do not contain non existing files include create_distrib.sh - create_distrib.sh: exit in case of error mkdir creates the parents directories if needed, 0.5.7 - 27 Nov 2001, Ludovic Rousseau - GemPC430/usblinux.c: crashed with two readers and no root priviledges - GemPC410/main.c: test code now support ISO 7816 case 1, 2, 3 and 4 using Jean-Luc ReaderTest Java applet (not included here) - common/GCUtils.c: add support for IFD_ICC_NOT_PRESENT GemCore error status - GemPC410/gbpserial.c: prepare to support multi serial readers - GemPC430/usbserial_mosx.c: prepare to support multi USB readers - GemPC410/gbpserial.c: use explain_gbp() to log a descriptive GBP level error message - MANIFEST: add README.410 - GemPC410/GemPC410Utils.c: log "OS string" at CRITICAL level to always have it the logs - GemPC430/GemPC430Utils.c: log "OS string" at CRITICAL level to always have it the logs - common/ifdhandler.c: Add APDU logging - common/GCdebug.h: add DEBUG_COMM3() and DEBUG_CRITICAL3() which is typically used to log error messages like "blabla /foo/bar: file not found" 0.5.6 - 15 Nov 2001, Ludovic Rousseau - all: migrate the type return value from RESPONSECODE to ifd_t, status_t or gcore_t - GCCmds.c: migrate from low level GCSendCommand() use to higer level and simpler GCMakeCommand() - libGemPC410 now supports long commands 0.5.5 - 7 Nov 2001, Ludovic Rousseau include Jean-Luc modifications to add a new protocol layer patch GemPC410 to support this layer include patches from the Debian package 0.5.4 - 28 Oct 2001, Ludovic Rousseau first public release I clarified the licences 0.5.3 - 26 Oct 2001, Ludovic Rousseau GemPC 410 and GemPC 430 compiles and runs 0.5.2bis - 23 Oct 2001, Jean-Luc Giraud Jean-Luc starts to dispatch ifdhandler.c 0.5.2 - 22 Oct 2001, Ludovic Rousseau first release containing GemPC410/ GemPC430/ and common/ 0.5 - 14 Oct 2001, Jean-Luc Giraud complete release containing the code for the GemPC 430 ?.? - 25 Sep 2001, Jean-Luc Giraud release of ifdhandler.{c,h} and GemCore.h $Id: README,v 1.41 2012-04-08 21:31:51 rousseau Exp $ vim:ts=20 ifd-gempc-1.0.7/README.4100000644000175000017500000000171310561621046015036 0ustar rousseaurousseauGemplus GemPC 410 reader driver README ====================================== /etc/reader.conf ================ The /etc/reader.conf should contain something like: FRIENDLYNAME "GemPC410" DEVICENAME /dev/ttyS0 LIBPATH /usr/local/pcsc/drivers/serial/libGemPC410.so.0 CHANNELID 1 Note that CHANNELID may be anything since it is not used by recent versions of pcscd (> 1.2.0) anymore and is deprecated. Be sure that DEVICENAME is really the device name you use. Under *BSD the serial ports are named /dev/cuaa* instead of /dev/ttyS*. /dev/pcsc/ directory ==================== /dev/pcsc/ is deprecated since pcscd now uses DEVICENAME instead of CHANNELID since the driver implement the ifdhandler API version 3.0. The driver does not use /dev/ttyS? (the serial port device) directly but uses /dev/pcsc/{1,2,3,4} which should be symbolic links to the real serial port devices. $Id: README.410,v 1.8 2004-01-20 14:34:39 rousseau Exp $ ifd-gempc-1.0.7/GemPC430/0000755000175000017500000000000011740401711015026 5ustar rousseaurousseauifd-gempc-1.0.7/GemPC430/TODO.txt0000644000175000017500000000112010561621210016324 0ustar rousseaurousseauGemPC430 todo list ================== - Add management of memory cards - Add PTS management (store it in set capabilities, send it in RESET/POWER_UP) - Implement IFDHSetCapabilities - Implement IFDHSetProtocolParameters - Implement IFDHControl - If receive buffer is too small for Data + SW, truncate data and always include SW - investigate the issue with 2 programs communicating with one reader. DONE ==== - Test T=1 mode - Check all GemCore possible status in status management functions - 3V cards are not currently supported. $Id: TODO.txt,v 1.3 2004-02-25 13:24:59 rousseau Exp $ ifd-gempc-1.0.7/GemPC430/usbserial.h0000644000175000017500000000110311740360155017171 0ustar rousseaurousseau/************************************************************** / Title: usbserial.h / Author: David Corcoran / Purpose: Abstracts usb API to serial like calls / $Id: usbserial.h,v 1.8 2012/04/08 19:01:01 rousseau Exp $ ***************************************************************/ #ifndef _USBSERIAL_H_ #define _USBSERIAL_H_ status_t OpenUSB( DWORD lun, DWORD channel ); status_t WriteUSB( DWORD lun, DWORD length, unsigned char *Buffer ); status_t ReadUSB( DWORD lun, DWORD *length, unsigned char *Buffer ); status_t CloseUSB( DWORD lun ); #endif ifd-gempc-1.0.7/GemPC430/.dependencies0000644000175000017500000000000011740401711017443 0ustar rousseaurousseauifd-gempc-1.0.7/GemPC430/libusb_wrap.h0000644000175000017500000000070410561621310017510 0ustar rousseaurousseau/* * libusb_wrap.h * Id$ * USB access routines using the libusb library * * Author: Ludovic Rousseau * Copyright (c) 2002 Ludovic Rousseau * License: See file COPYING.GPL */ #ifndef _LIBUSB_WRAP_ #define _LIBUSB_WRAP_ status_t OpenUSB( DWORD lun, LPSTR device ); status_t WriteUSB( DWORD lun, DWORD length, unsigned char *Buffer ); status_t ReadUSB( DWORD lun, DWORD *length, unsigned char *Buffer ); status_t CloseUSB( DWORD lun ); #endif ifd-gempc-1.0.7/GemPC430/GemPC430Utils.c0000644000175000017500000000316411170331326017402 0ustar rousseaurousseau/* * GemPC430Utils.c * $Id: GemPC430Utils.c,v 1.20 2009-04-12 09:22:30 rousseau Exp $ * GemPC430 dedicated functions * * Created by giraud on Sat Oct 20 2001. * Copyright (c) 2001 Jean-Luc Giraud. * 2001-2004 Ludovic Rousseau * License: See file COPYING * */ #include #include "gempc_ifdhandler.h" #include "Config.h" #include "GemPC430Utils.h" #include "GemCore.h" #include "GCCmds.h" #include "libusb_wrap.h" #include "GCdebug.h" #include "GCTransport.h" ifd_t OpenGemPC430ByName(DWORD lun, LPSTR dev_name) { UCHAR os_version[IFD_LEN_VERSION+2]; DWORD length; if (OpenUSB(lun, dev_name) != STATUS_SUCCESS) { DEBUG_CRITICAL("OpenUSB failed"); return IFD_COMMUNICATION_ERROR; } /* Set the mode to ROS but no TLP (ATR should then be fine) */ if ( GCCmdSetMode(lun, IFD_MODE_ROSNOTLP) != IFD_SUCCESS ) { DEBUG_CRITICAL("Setmode failed"); CloseUSB(lun); return IFD_COMMUNICATION_ERROR; } /* Get the GemCore OS version */ length = sizeof(os_version); if (GCCmdGetOSVersion(lun, &length, os_version) != IFD_SUCCESS) { DEBUG_CRITICAL("GCCmdGetOSVersion failed"); return IFD_COMMUNICATION_ERROR; } /* Not really critical but shall be logged */ DEBUG_CRITICAL2("OS string: %s", os_version); return IFD_SUCCESS; } /* OpenGemPC430ByName */ ifd_t OpenGemPC430(DWORD lun, DWORD channel) { (void)channel; return OpenGemPC430ByName(lun, NULL); } /* OpenGemPC430 */ ifd_t CloseGemPC430(DWORD lun) { if ( CloseUSB(lun) != STATUS_SUCCESS) return IFD_COMMUNICATION_ERROR; return IFD_SUCCESS; } /* CloseGemPC430 */ ifd-gempc-1.0.7/GemPC430/libusb_wrap.c0000644000175000017500000002027511740361172017517 0ustar rousseaurousseau/* * libusb_wrap.c * $Id: libusb_wrap.c,v 1.24 2012/04/08 19:09:46 rousseau Exp $ * USB access routines using the libusb library * * Created by Ludovic Rousseau on Sep 27 2002 * Copyright (c) 2002 Ludovic Rousseau * License: See file COPYING.GPL */ #include #include #include #include #include "gempc_ifdhandler.h" #include "Config.h" #include "GCdebug.h" #include "GCUtils.h" #include "GemCore.h" #include "libusb_wrap.h" #define USB_INEP 0 #define USB_OUTEP 1 /* read timeout * we must wait enough so that the card can finish its calculation */ #define USB_READ_TIMEOUT 60000 /* 1 minute timeout */ /* write timeout * we don't have to wait a long time since the card was doing nothing */ #define USB_WRITE_TIMEOUT 5000 /* 5 seconds timeout */ typedef struct { int kMyVendorID; int kMyProductID; } _usbID; /* * Add an entry to match your reader. */ static _usbID UsbIDs[] = { { 0x08E6, 0x0430 }, /* GemPC 430 */ { 0x08E6, 0x0432 }, /* GemPC 432 */ { 0x08E6, 0x0435 } /* GemPC 435 */ }; /* used to store string %s/%s (dirname/filename) like: * (/proc/bus/usb/) 001/002 (Linux) * /dev/usb0//dev/ (FreeBSD) * /dev/usb0//dev/ugen0 (OpenBSD) */ #define BUS_DEVICE_STRSIZE 32 typedef struct { usb_dev_handle *handle; struct usb_device *dev; int interface; /* * Endpoints */ int bulk_in; int bulk_out; } _usbDevice; #if (PCSCLITE_MAX_READERS-16) #error Edit this file and set the number of initialiser to PCSCLITE_MAX_READERS (default was 16 but it has changed) #endif static _usbDevice usbDevice[PCSCLITE_MAX_READERS] = { [ 0 ... (PCSCLITE_MAX_READERS-1) ] = { NULL, NULL, 0, 0, 0 } }; /***************************************************************************** * * OpenUSB * ****************************************************************************/ status_t OpenUSB(DWORD lun, LPSTR device) { static struct usb_bus *busses = NULL; int id, id_number; int reader = LunToReaderIndex(lun); struct usb_bus *bus; struct usb_dev_handle *dev_handle; int device_vendor, device_product; DEBUG_COMM3("Lun: %lX, Device: %s", lun, device); /* device name specified */ if (device) { if (strncmp("usb:", device, 4) != 0) { DEBUG_CRITICAL2("device name does not start with \"usb:\": %s", device); return STATUS_UNSUCCESSFUL; } if (sscanf(device, "usb:%x/%x", &device_vendor, &device_product) != 2) { DEBUG_CRITICAL2("device name can't be parsed: %s", device); return STATUS_UNSUCCESSFUL; } } if (busses == NULL) usb_init(); usb_find_busses(); usb_find_devices(); busses = usb_get_busses(); if (busses == NULL) { DEBUG_CRITICAL("No USB busses found"); return STATUS_UNSUCCESSFUL; } /* is the lun already used? */ if (usbDevice[reader].handle != NULL) { DEBUG_CRITICAL2("USB driver with lun %lX already in use", lun); return STATUS_UNSUCCESSFUL; } /* find any devide corresponding to a UsbIDs entry */ id_number = sizeof(UsbIDs)/sizeof(UsbIDs[0]); /* for any supported reader */ for (id=0; idnext) { struct usb_device *dev; /* any device on this bus */ for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == UsbIDs[id].kMyVendorID && dev->descriptor.idProduct == UsbIDs[id].kMyProductID) { int r, already_used; int interface; /* is it already opened? */ already_used = FALSE; for (r=0; rdirname, dev->filename); if (strcmp(usbDevice[r].dev->bus->dirname, bus->dirname) == 0 && strcmp(usbDevice[r].dev->filename, dev->filename) == 0) already_used = TRUE; } } /* this reader is already managed by us */ if (already_used) { DEBUG_INFO3("USB device %s/%s already in use. Checking next one.", bus->dirname, dev->filename); continue; } DEBUG_COMM3("Trying to open USB device: %s/%s", bus->dirname, dev->filename); dev_handle = usb_open(dev); if (dev_handle == NULL) { DEBUG_CRITICAL4("Can't usb_open(%s/%s): %s", bus->dirname, dev->filename, strerror(errno)); continue; } /* now we found a free reader and we try to use it */ if (dev->config == NULL) { DEBUG_CRITICAL3("No dev->config found for %s/%s", bus->dirname, dev->filename); return STATUS_UNSUCCESSFUL; } interface = dev->config->interface->altsetting->bInterfaceNumber; if (usb_claim_interface(dev_handle, interface) < 0) { DEBUG_CRITICAL4("Can't claim interface %s/%s: %s", bus->dirname, dev->filename, strerror(errno)); return STATUS_UNSUCCESSFUL; } DEBUG_COMM3("Using USB device: %s/%s", bus->dirname, dev->filename); /* store device information */ usbDevice[reader].handle = dev_handle; usbDevice[reader].dev = dev; usbDevice[reader].interface = interface; usbDevice[reader].bulk_in = usbDevice[reader].dev->config->interface->altsetting->endpoint[USB_INEP].bEndpointAddress; usbDevice[reader].bulk_out = usbDevice[reader].dev->config->interface->altsetting->endpoint[USB_OUTEP].bEndpointAddress; goto end; } } } } if (usbDevice[reader].handle == NULL) return STATUS_UNSUCCESSFUL; end: return STATUS_SUCCESS; } /* OpenUSB */ /***************************************************************************** * * WriteUSB * ****************************************************************************/ status_t WriteUSB(DWORD lun, DWORD length, unsigned char *buffer) { int rv; int reader = LunToReaderIndex(lun); char debug_header[] = "-> 121234 "; sprintf(debug_header, "-> %06X ", (int)lun); DEBUG_XXD(debug_header, buffer, length); rv = usb_bulk_write(usbDevice[reader].handle, usbDevice[reader].bulk_out, (char *)buffer, length, USB_WRITE_TIMEOUT); if (rv < 0) { if (usbDevice[reader].dev->bus) { DEBUG_CRITICAL4("%s/%s: %s", usbDevice[reader].dev->bus->dirname, usbDevice[reader].dev->filename, strerror(errno)); /* reset in case of timeout (usually means a reader freeze) * The application will receive an error but can try to reconnect. * Without the patch the reader must be physically * unpluged-repluged */ if (errno == ETIMEDOUT) { DEBUG_CRITICAL3("Reseting the reader: %s/%s", usbDevice[reader].dev->bus->dirname, usbDevice[reader].dev->filename); usb_reset(usbDevice[reader].handle); } } else DEBUG_CRITICAL2("usb_bulk_write(no device): %s", strerror(errno)); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; } /* WriteUSB */ /***************************************************************************** * * ReadUSB * ****************************************************************************/ status_t ReadUSB(DWORD lun, DWORD * length, unsigned char *buffer) { int rv; int reader = LunToReaderIndex(lun); char debug_header[] = "<- 121234 "; sprintf(debug_header, "<- %06X ", (int)lun); rv = usb_bulk_read(usbDevice[reader].handle, usbDevice[reader].bulk_in, (char *)buffer, *length, USB_READ_TIMEOUT); *length = rv; if (rv < 0) { DEBUG_CRITICAL4("%s/%s: %s", usbDevice[reader].dev->bus->dirname, usbDevice[reader].dev->filename, strerror(errno)); return STATUS_UNSUCCESSFUL; } DEBUG_XXD(debug_header, buffer, *length); return STATUS_SUCCESS; } /* ReadUSB */ /***************************************************************************** * * CloseUSB * ****************************************************************************/ status_t CloseUSB(DWORD lun) { int reader = LunToReaderIndex(lun); DEBUG_COMM3("device: %s/%s", usbDevice[reader].dev->bus->dirname, usbDevice[reader].dev->filename); usb_release_interface(usbDevice[reader].handle, usbDevice[reader].interface); usb_close(usbDevice[reader].handle); /* mark the resource unused */ usbDevice[reader].handle = NULL; usbDevice[reader].dev = NULL; return STATUS_SUCCESS; } /* CloseUSB */ ifd-gempc-1.0.7/GemPC430/GCUSBTransport.c0000644000175000017500000000350111740361172017757 0ustar rousseaurousseau/* * $Id: GCUSBTransport.c,v 1.6 2012/04/08 19:09:46 rousseau Exp $ * ifd-GemPC * * Created by JL Giraud on Sun Nov 19 2000. * Updated by Ludovic Rousseau , Oct 2001 * * Transport level for the GemPC430 of Gemplus. * * License: See file COPYING * */ #include #include "gempc_ifdhandler.h" #include "Config.h" #include "GCTransport.h" #include "usbserial.h" status_t GCSendCommand(DWORD Lun, DWORD nLengthIn, const UCHAR pcBufferCmd[], PDWORD pnLengthOut, UCHAR pcBufferOut[]) { UCHAR pctr_to_card_buffer[GC_TR_BUF_SIZE]; status_t creturn_value; DWORD nlength; creturn_value = STATUS_SUCCESS; if (GC_TR_BUF_SIZE <= nLengthIn) { /* Buffer is too small (should not happen) */ creturn_value = STATUS_DEVICE_PROTOCOL_ERROR; goto finally; } memcpy(pctr_to_card_buffer+1, pcBufferCmd, nLengthIn); pctr_to_card_buffer[TR_OFFSET_LNG] = nLengthIn; if (WriteUSB(Lun, nLengthIn+1, pctr_to_card_buffer) != STATUS_SUCCESS) { creturn_value = STATUS_DEVICE_PROTOCOL_ERROR; goto finally; } nlength = sizeof(pctr_to_card_buffer); if (ReadUSB(Lun, &nlength, pctr_to_card_buffer) != STATUS_SUCCESS) { creturn_value = STATUS_DEVICE_PROTOCOL_ERROR; goto finally; } if ( nlength < 1 ) { /* length byte not received */ creturn_value = STATUS_DEVICE_PROTOCOL_ERROR; goto finally; } nlength--; *pnLengthOut = (*pnLengthOut #include #include #include #include #include #include #include #include #include #include #include "Config.h" #include "gempc_ifdhandler.h" #include "GemCore.h" #include "GCdebug.h" #include "usbserial.h" #define USBMAX_READERS 16 // Read time out in milliseconds unsigned long ReadTimeOut = 60000; /* Change the following to uniquely match your reader. */ /*enum { kMyDeviceClass = kIOUSBAnyClass, kMyDeviceSubClass = kIOUSBAnySubClass, kMyDeviceProtocol = kIOUSBAnyProtocol }; */ static int iInitialized = FALSE; typedef struct _intFace { IOUSBInterfaceInterface182 **iface; IOUSBDeviceInterface182 **dev; UInt32 usbAddr; UInt8 inPipeRef; UInt8 outPipeRef; } intrFace, *pIntrFace; static pIntrFace intFace[USBMAX_READERS]; void FreeintFace(); void FreeintFace() { int i; for (i=0; i < USBMAX_READERS; i++) { free(intFace[i]); } } status_t OpenUSB( DWORD lun, DWORD Channel) { CFMutableDictionaryRef USBMatch = 0; io_iterator_t iter = 0; io_service_t USBDevice = 0; io_service_t USBIface = 0; kern_return_t kr; io_iterator_t iterB = 0; SInt32 score; IOUSBFindInterfaceRequest findInterface; IOCFPlugInInterface **iodev=NULL; IOCFPlugInInterface **iodevB=NULL; HRESULT res; DWORD rdrLun; SInt32 hpManu_id, hpProd_id; UInt32 usbAddr,usbAddrtest; short iFound; int i; IOUSBConfigurationDescriptorPtr confDesc; UInt8 intfNumEndpoints; UInt8 direction, number, transferType, interval; UInt16 maxPacketSize; mach_port_t masterPort; CFBundleRef myBundle; CFStringRef propertyString; CFDictionaryRef bundleInfoDict; const char *cStringValue; DEBUG_INFO(""); hpManu_id = 0; hpProd_id = 0; // Look for a bundle using its identifier if (!(myBundle = CFBundleGetBundleWithIdentifier(CFSTR("free.pcsc.GemPC430") ))) { DEBUG_CRITICAL("Bundle Identifier not found"); return STATUS_UNSUCCESSFUL; } bundleInfoDict = CFBundleGetInfoDictionary(myBundle); if (bundleInfoDict == NULL) { DEBUG_CRITICAL("Bundle InfoDic error"); return STATUS_UNSUCCESSFUL; } propertyString = CFDictionaryGetValue(bundleInfoDict, CFSTR("ifdVendorID")); if (propertyString == NULL) { DEBUG_CRITICAL("Bundle InfoDic error: ifdVendorID not found"); return STATUS_UNSUCCESSFUL; } cStringValue = CFStringGetCStringPtr(propertyString, CFStringGetSystemEncoding()); hpManu_id = strtoul(cStringValue, 0, 16); propertyString = CFDictionaryGetValue(bundleInfoDict, CFSTR("ifdProductID")); if (propertyString == 0) { DEBUG_CRITICAL("Bundle InfoDic error: ifdProductID not found"); return STATUS_UNSUCCESSFUL; } cStringValue = CFStringGetCStringPtr(propertyString, CFStringGetSystemEncoding()); hpProd_id = strtoul(cStringValue, 0, 16); propertyString = CFDictionaryGetValue(bundleInfoDict, CFSTR("ifdReadTimeOut")); if (propertyString == 0) { DEBUG_CRITICAL("Bundle InfoDic error: could find ifdReadTimeOut, keep default"); } else { cStringValue = CFStringGetCStringPtr(propertyString, CFStringGetSystemEncoding()); ReadTimeOut = strtoul(cStringValue, 0, 10); } DEBUG_CRITICAL2("Driver configured to detect Vendor ID = %04X", hpManu_id); DEBUG_CRITICAL2("Driver configured to detect Product ID = %04X", hpProd_id); iFound = FALSE; rdrLun = lun >> 16; if ( iInitialized == FALSE ) { for (i=0; i < USBMAX_READERS; i++) { intFace[i] = (pIntrFace)malloc(sizeof(intrFace)); if (!intFace[i]) { /* Malloc failed! */ DEBUG_CRITICAL("Couldn't malloc structure: "); return STATUS_UNSUCCESSFUL; } (intFace[i])->usbAddr = 0; (intFace[i])->dev = NULL; (intFace[i])->iface = NULL; (intFace[i])->inPipeRef = 0; (intFace[i])->outPipeRef = 0; } iInitialized = TRUE; } /* first create a master_port for my task */ kr = IOMasterPort(bootstrap_port, &masterPort); if (kr || !masterPort) { DEBUG_CRITICAL2("Couldn't create a master IOKit Port (0x%08X)", kr); FreeintFace(); return STATUS_UNSUCCESSFUL; } USBMatch = IOServiceMatching(kIOUSBDeviceClassName); if (!USBMatch) { DEBUG_CRITICAL("Can't create a USB matching dictionary"); mach_port_deallocate(mach_task_self(), masterPort); FreeintFace(); return STATUS_UNSUCCESSFUL; } CFDictionarySetValue(USBMatch, CFSTR(kUSBVendorName), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &hpManu_id)); CFDictionarySetValue(USBMatch, CFSTR(kUSBProductName), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &hpProd_id)); /* create an iterator over all matching IOService nubs */ kr = IOServiceGetMatchingServices(masterPort, USBMatch, &iter); if (kr) { DEBUG_CRITICAL2("Can't create a USB Service iterator (0x%08X)", kr); //? CFRelease(USBMatch); mach_port_deallocate(mach_task_self(), masterPort); return STATUS_UNSUCCESSFUL; } // masterPort not used any more mach_port_deallocate(mach_task_self(), masterPort); while ( (USBDevice = IOIteratorNext(iter)) ) { kr = IOCreatePlugInInterfaceForService(USBDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score); IOObjectRelease(USBDevice); /* done with the device object now */ if (kr || !iodev) { DEBUG_CRITICAL2("unable to create a plugin (0x%08X)", kr); continue; } /* i have the device plugin. I need the device interface */ res = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID)&(intFace[rdrLun])->dev); //(*iodev)->Release(iodev); if (res || !(intFace[rdrLun])->dev) { DEBUG_CRITICAL2("Couldn't create a device interface (0x%08X)", (int)res); continue; } kr = (*(intFace[rdrLun])->dev)->GetLocationID(((intFace[rdrLun])->dev), &usbAddr); for (i=0; i < USBMAX_READERS; i++) { if ( usbAddr == (intFace[i])->usbAddr ) { iFound = TRUE; break; } } if ( iFound ) { iFound = FALSE; continue; } /* We found it now lets break out of the loop */ break; } if ((intFace[rdrLun])->dev == NULL) { /* Device not found */ CFRelease(USBMatch); return STATUS_UNSUCCESSFUL; } kr = (*(intFace[rdrLun])->dev)->GetLocationID(((intFace[rdrLun])->dev), &usbAddrtest); kr = (*(intFace[rdrLun])->dev)->USBDeviceOpen(((intFace[rdrLun])->dev)); if (kr == kIOReturnExclusiveAccess) { sleep(1); // Try to re-open in case Classic is using the device if( kr = (*(intFace[rdrLun])->dev)->USBDeviceOpenSeize(((intFace[rdrLun])->dev)) ) { DEBUG_CRITICAL2("unable to open device: 0x%08X", kr); (*(intFace[rdrLun])->dev)->Release(((intFace[rdrLun])->dev)); return STATUS_UNSUCCESSFUL; } } else { if ( kr != kIOReturnSuccess) { DEBUG_CRITICAL2("unable to open device, not kIOReturnExclusiveAccess: 0x%08X", kr); (*(intFace[rdrLun])->dev)->Release(((intFace[rdrLun])->dev)); return STATUS_UNSUCCESSFUL; } } kr = (*(intFace[rdrLun])->dev)->GetConfigurationDescriptorPtr(((intFace[rdrLun])->dev), 0, &confDesc); if (kr) { DEBUG_CRITICAL("ERR: unable to get the configuration"); (*(intFace[rdrLun])->dev)->USBDeviceClose(((intFace[rdrLun])->dev)); (*(intFace[rdrLun])->dev)->Release(((intFace[rdrLun])->dev)); return STATUS_UNSUCCESSFUL; } (*(intFace[rdrLun])->dev)->ResetDevice(((intFace[rdrLun])->dev)); kr = (*(intFace[rdrLun])->dev)->SetConfiguration(((intFace[rdrLun])->dev), confDesc->bConfigurationValue); if (kr) { DEBUG_CRITICAL("ERR: unable to set the configuration"); (*(intFace[rdrLun])->dev)->USBDeviceClose(((intFace[rdrLun])->dev)); (*(intFace[rdrLun])->dev)->Release(((intFace[rdrLun])->dev)); return STATUS_UNSUCCESSFUL; } /* Time to find the first interface */ findInterface.bInterfaceClass = kIOUSBFindInterfaceDontCare; findInterface.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; findInterface.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; findInterface.bAlternateSetting = kIOUSBFindInterfaceDontCare; kr = (*(intFace[rdrLun])->dev)->CreateInterfaceIterator( ((intFace[rdrLun])->dev), &findInterface, &iterB ); USBIface = IOIteratorNext(iterB); if ( USBIface == 0 ) { DEBUG_CRITICAL("No interface found"); return STATUS_UNSUCCESSFUL; } score = 0; /* Create the plugin for the interface service */ kr = IOCreatePlugInInterfaceForService(USBIface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &iodevB, &score); res = (*iodev)->QueryInterface(iodevB, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID)&(intFace[rdrLun])->iface); (intFace[rdrLun])->usbAddr = usbAddr; /* Open the interface to open all the pipes */ kr = (*(intFace[rdrLun])->iface)->USBInterfaceOpen((intFace[rdrLun])->iface); if (kr != kIOReturnSuccess ) { DEBUG_CRITICAL2("unable to open device: 0x%08X", kr); return STATUS_UNSUCCESSFUL; } if (iter) { IOObjectRelease(iter); iter = 0; } // Get nb of end points kr = (*(intFace[rdrLun])->iface)->GetNumEndpoints((intFace[rdrLun])->iface, &intfNumEndpoints); if (kr != kIOReturnSuccess ) { DEBUG_CRITICAL2("unable to get number of end points: 0x%08X", kr); return STATUS_UNSUCCESSFUL; } // pipes are one based, since zero is the default control pipe for (i=1; i <= intfNumEndpoints; i++) { kr = (*(intFace[rdrLun])->iface)->GetPipeProperties((intFace[rdrLun])->iface, i, &direction, &number, &transferType, &maxPacketSize, &interval); if (kr != kIOReturnSuccess ) { DEBUG_CRITICAL2("unable to get pipe properties: 0x%08X", kr); return STATUS_UNSUCCESSFUL; } if (transferType != kUSBBulk) { continue; } if ((direction == kUSBIn) && !((intFace[rdrLun])->inPipeRef)) { (intFace[rdrLun])->inPipeRef = i; } if ((direction == kUSBOut) && !((intFace[rdrLun])->outPipeRef)) { (intFace[rdrLun])->outPipeRef = i; } } if ( !((intFace[rdrLun])->outPipeRef) ) { DEBUG_CRITICAL2("unable to get outPipe: 0x%08X", kr); CloseUSB(lun); return STATUS_UNSUCCESSFUL; } if (!( (intFace[rdrLun])->inPipeRef)) { DEBUG_CRITICAL2("unable to get inPipe: 0x%08X", kr); CloseUSB(lun); return STATUS_UNSUCCESSFUL; } DEBUG_CRITICAL2("New reader found at USB address: %08X", (intFace[rdrLun])->usbAddr); return STATUS_SUCCESS; } status_t WriteUSB( DWORD lun, DWORD length, unsigned char *buffer ) { IOReturn iorv; DWORD rdrLun; rdrLun = lun >> 16; DEBUG_XXD("Attempt to write: ", buffer, length); /* Make sure the pipe is OK */ iorv = (*(intFace[rdrLun])->iface)->GetPipeStatus( (intFace[rdrLun])->iface, (intFace[rdrLun])->outPipeRef ); if ( iorv != kIOReturnSuccess ) { return STATUS_UNSUCCESSFUL; } /* Write the data */ iorv = (*(intFace[rdrLun])->iface)->WritePipe((intFace[rdrLun])->iface, (intFace[rdrLun])->outPipeRef, buffer, length); if ( iorv != kIOReturnSuccess ) { return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; } status_t ReadUSB( DWORD lun, DWORD *length, unsigned char *buffer ) { IOReturn iorv; UInt32 recvLen; UInt32 noDataTO, completeTO; DWORD rdrLun; rdrLun = lun >> 16; DEBUG_COMM2("Attempt to read %ld bytes", *length); /* Make sure the pipe is OK */ iorv = (*(intFace[rdrLun])->iface)->GetPipeStatus( (intFace[rdrLun])->iface, (intFace[rdrLun])->inPipeRef ); if ( iorv != kIOReturnSuccess ) { return STATUS_UNSUCCESSFUL; } /* Try to read up to 256 bytes */ recvLen = 256; completeTO = ReadTimeOut; noDataTO = ReadTimeOut; iorv = (*(intFace[rdrLun])->iface)->ReadPipeTO( (intFace[rdrLun])->iface, (intFace[rdrLun])->inPipeRef, buffer, &recvLen, noDataTO, completeTO); if ( iorv != 0 ) { (*(intFace[rdrLun])->dev)->ResetDevice(((intFace[rdrLun])->dev)); return STATUS_UNSUCCESSFUL; } DEBUG_XXD("received: ", buffer, recvLen); *length = recvLen; return STATUS_SUCCESS; } status_t CloseUSB( DWORD lun ) { IOReturn iorv; DWORD rdrLun; rdrLun = lun >> 16; // Reset struct (intFace[rdrLun])->usbAddr = 0; (intFace[rdrLun])->outPipeRef = 0; (intFace[rdrLun])->inPipeRef = 0; /* Close the interface and rid the iterator */ iorv = (*(intFace[rdrLun])->iface)->USBInterfaceClose( (intFace[rdrLun])->iface ); if (iorv) { DEBUG_CRITICAL2("ERR: Couldn't close interface (%08x)", (int)iorv); } /* Release the interface */ (*(intFace[rdrLun])->iface)->Release((intFace[rdrLun])->iface); iorv = (*(intFace[rdrLun])->dev)->USBDeviceClose((intFace[rdrLun])->dev); if (iorv) { DEBUG_CRITICAL2("ERR: Couldn't close device (%08x)", (int)iorv); } (*(intFace[rdrLun])->dev)->Release((intFace[rdrLun])->dev); if ( iorv != kIOReturnSuccess ) { return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; } ifd-gempc-1.0.7/GemPC430/Info.plist0000644000175000017500000000225610445301072017003 0ustar rousseaurousseau CFBundleDevelopmentRegion English CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType BNDL CFBundleSignature ???? CFBundleVersion 0.0.1d1 ifdCapabilities 0x00000000 ifdProtocolSupport 0x00000001 ifdVersionNumber 0x00000001 CFBundleExecutable libGemPC430.so.VERSION ifdManufacturerString Gemplus SA ifdProductString GemPC430 ifdVendorID 0x08E6 0x08E6 0x08E6 ifdProductID 0x0430 0x0432 0x0435 ifdFriendlyName GemPC430 GemPC432 GemPC435 ifd-gempc-1.0.7/GemPC430/COPYING0000644000175000017500000000260610445301072016065 0ustar rousseaurousseauCopyright (c) 2001 Jean-Luc Giraud All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ifd-gempc-1.0.7/GemPC430/Config.h0000644000175000017500000000107310561621210016403 0ustar rousseaurousseau/* * $Id: Config.h,v 1.14 2005-06-17 10:37:35 rousseau Exp $ * ifd-GemPC430 * * Created by JL Giraud on Sun Nov 19 2000. * License: See file COPYING * */ #ifndef __CONFIG_H__ #define __CONFIG_H__ /* Perform automatic PPS negociation * unsed by default for safety instead of speed */ /* #define AUTOMATIC_PPS */ /* GemPC430 specific */ #define OpenPort OpenGemPC430 #define OpenPortByName OpenGemPC430ByName #define ClosePort CloseGemPC430 #define ReadPort ReadUSB #define WritePort WriteUSB #define READER_NAME "GemPC43x" #endif ifd-gempc-1.0.7/GemPC430/GemPC430Utils.h0000644000175000017500000000067010561621557017421 0ustar rousseaurousseau/* * GemPC430Utils.h * $Id: GemPC430Utils.h,v 1.8 2007-02-05 12:30:39 rousseau Exp $ * GemPC430 dedicated functions * * Created by giraud on Sat Oct 20 2001. * Copyright (c) 2001 Jean-Luc Giraud. * License: See file COPYING * */ #ifndef _GEMPC430UTILS_H_ #define _GEMPC430UTILS_H_ ifd_t OpenGemPC430ByName(DWORD lun, LPSTR dev_name); ifd_t OpenGemPC430(DWORD lun, DWORD channel); ifd_t CloseGemPC430(DWORD lun); #endif ifd-gempc-1.0.7/GemPC430/Makefile0000644000175000017500000000437011740361522016477 0ustar rousseaurousseau# # $Id: Makefile,v 1.50 2012/04/08 19:13:22 rousseau Exp $ # # set these paths to where you installed pcsc-lite and libusb # you can use more than one path in each variable INCS = -I/usr/local/include `pkg-config libpcsclite --cflags` LIBS = -L/usr/local/lib -lusb INSTALL_DIR = $(DESTDIR)`pkg-config libpcsclite --variable=usbdropdir` # use a correct default CFLAGS ifeq ($(CFLAGS),) CFLAGS = -O2 -g -Wall -fPIC -I. -I../common -DGEMPC=430 $(INCS) else CFLAGS += -Wall -fPIC -I. -I../common -DGEMPC=430 $(INCS) endif # /home/rousseau/sc/pcsc/i/ifd-gempc-0.5.10/GemPC410 -> 0.5.10 version=$(shell expr `pwd` : '.*-\([0-9.]*\)') targets= GCUSBTransport.o libusb_wrap.o GemPC430Utils.o common_targets= ../common/ifdhandler.o ../common/GCCmds.o ../common/GCUtils.o all: check expert check: check_stamp check_stamp: CFLAGS="$(INCS)" LIBS="$(LIBS)" ../check 430 touch check_stamp expert: ifd-GemPC430 libGemPC430.so common: $(MAKE) -C ../common CFLAGS="$(CFLAGS) -I../GemPC430" all ifd-GemPC430: common $(targets) main.o ../common/GCdebug.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(targets) $(common_targets) main.o ../common/GCdebug.o $(LIBS) libGemPC430.so: common $(targets) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ $(targets) $(common_targets) $(LIBS) main.o: ../GemPC410/main.c $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -c -o $@ $^ clean: rm -f .dependencies touch .dependencies rm -f $(targets) rm -f libGemPC430.so ifd-GemPC430.bundle/Contents/Linux/libGemPC430.so.$(version) rm -f ifd-GemPC430 main.o $(MAKE) -C ../common clean rm -f Makefile.bak rm -f config.log distclean: clean rm -f tags rm -f check_stamp dep_stamp install: all mkdir -p $(INSTALL_DIR)/ifd-GemPC430.bundle/Contents/Linux/ cp libGemPC430.so $(INSTALL_DIR)/ifd-GemPC430.bundle/Contents/Linux/libGemPC430.so.$(version) sed s/VERSION/$(version)/ Info.plist > $(INSTALL_DIR)/ifd-GemPC430.bundle/Contents/Info.plist dep: dep_stamp dep_stamp: @echo "Making dependencies..." makedepend -f - -I. -I../common -DGEMPC=430 GCUSBTransport.c \ GemPC430Utils.c libusb_wrap.c > .dependencies || true $(MAKE) -C ../common dep touch dep_stamp .dependencies: dep ctags: ctags-exuberant *.h *.c ../common/*.h ../common/*.c .PHONY: all common clean distclean dep ctags expert check include .dependencies ifd-gempc-1.0.7/MacOSXbuild/0000755000175000017500000000000011740401711015756 5ustar rousseaurousseauifd-gempc-1.0.7/MacOSXbuild/debuglog.h0000644000175000017500000000556011146613225017732 0ustar rousseaurousseau/* * MUSCLE SmartCard Development ( http://www.linuxnet.com ) * * Copyright (C) 1999-2004 * David Corcoran * Copyright (C) 1999-2005 * Ludovic Rousseau * * $Id: debuglog.h,v 1.1 2009-02-17 19:57:09 rousseau Exp $ */ /** * @file * @brief This handles debugging. * * @note log message is sent to syslog or stderr depending on --foreground * command line argument * * @code * Log1(priority, "text"); * log "text" with priority level priority * Log2(priority, "text: %d", 1234); * log "text: 1234" * the format string can be anything printf() can understand * Log3(priority, "text: %d %d", 1234, 5678); * log "text: 1234 5678" * the format string can be anything printf() can understand * LogXxd(priority, msg, buffer, size); * log "msg" + a hex dump of size bytes of buffer[] * @endcode */ #ifndef __debuglog_h__ #define __debuglog_h__ #ifdef __cplusplus extern "C" { #endif #ifndef PCSC_API #define PCSC_API #endif #define DEBUGLOG_LOG_ENTRIES 1 #define DEBUGLOG_IGNORE_ENTRIES 2 enum { DEBUGLOG_NO_DEBUG = 0, DEBUGLOG_SYSLOG_DEBUG, DEBUGLOG_STDERR_DEBUG }; #define DEBUG_CATEGORY_NOTHING 0 #define DEBUG_CATEGORY_APDU 1 #define DEBUG_CATEGORY_SW 2 enum { PCSC_LOG_DEBUG = 0, PCSC_LOG_INFO, PCSC_LOG_ERROR, PCSC_LOG_CRITICAL }; /* You can't do #ifndef __FUNCTION__ */ #if !defined(__GNUC__) && !defined(__IBMC__) #define __FUNCTION__ "" #endif #define Log0(priority) log_msg(priority, "%s:%d:%s()", __FILE__, __LINE__, __FUNCTION__) #define Log1(priority, fmt) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__) #define Log2(priority, fmt, data) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data) #define Log3(priority, fmt, data1, data2) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2) #define Log4(priority, fmt, data1, data2, data3) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3) #define Log9(priority, fmt, data1, data2, data3, data4, data5, data6, data7, data8) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3, data4, data5, data6, data7, data8) #define LogXxd(priority, msg, buffer, size) log_xxd(priority, msg, buffer, size) #define DebugLogA(a) Log1(PCSC_LOG_INFO, a) #define DebugLogB(a, b) Log2(PCSC_LOG_INFO, a, b) #define DebugLogC(a, b,c) Log3(PCSC_LOG_INFO, a, b, c) PCSC_API void log_msg(const int priority, const char *fmt, ...); PCSC_API void log_xxd(const int priority, const char *msg, const unsigned char *buffer, const int size); void DebugLogSuppress(const int); void DebugLogSetLogType(const int); int DebugLogSetCategory(const int); void DebugLogCategory(const int, const unsigned char *, const int); PCSC_API void DebugLogSetLevel(const int level); #ifdef __cplusplus } #endif #endif /* __debuglog_h__ */ ifd-gempc-1.0.7/MacOSXbuild/ifd-GemPC430/0000755000175000017500000000000011740401711017700 5ustar rousseaurousseauifd-gempc-1.0.7/MacOSXbuild/ifd-GemPC430/English.lproj/0000755000175000017500000000000011740401711022416 5ustar rousseaurousseauifd-gempc-1.0.7/MacOSXbuild/ifd-GemPC430/English.lproj/InfoPlist.strings0000644000175000017500000000121210445301073025735 0ustar rousseaurousseauþÿ/* Localized versions of Info.plist keys */ CFBundleName = "ifd-GemPC430"; CFBundleShortVersionString = "ifd-GemPC430 version 0.5.5"; CFBundleGetInfoString = "ifd-GemPC430 version 0.5.5, Copyright 2001, Jean-Luc Giraud <jlgiraud@mac.com>."; NSHumanReadableCopyright = "Copyright 2001, Jean-Luc Giraud <jlgiraud@mac.com>."; ifd-gempc-1.0.7/MacOSXbuild/ifd-GemPC430/ifd-GemPC430.xcodeproj/0000755000175000017500000000000011740401711023616 5ustar rousseaurousseauifd-gempc-1.0.7/MacOSXbuild/ifd-GemPC430/ifd-GemPC430.xcodeproj/project.pbxproj0000644000175000017500000004455411147054543026716 0ustar rousseaurousseau// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 42; objects = { /* Begin PBXBuildFile section */ 089C1680FE841241C02AAC07 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; 0AA190A0FE8422F4C02AAC07 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */; }; 1FD8F21B0F49A7AE0083CF66 /* ifdhandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FD8F21A0F49A7AE0083CF66 /* ifdhandler.h */; }; 1FD8F2260F49A8010083CF66 /* gempc_ifdhandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FD8F2250F49A8010083CF66 /* gempc_ifdhandler.h */; }; 1FD8F23D0F49A86C0083CF66 /* debuglog.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FD8F23C0F49A86C0083CF66 /* debuglog.h */; }; F5879BEF0195AEC8019AD40F /* GCCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F5879BEE0195AEC8019AD40F /* GCCmds.c */; }; F5879BFA0195AF5C019AD40F /* GCTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = F5879BF00195AF5C019AD40F /* GCTransport.h */; }; F5879BFB0195AF5C019AD40F /* GCCmds.h in Headers */ = {isa = PBXBuildFile; fileRef = F5879BF10195AF5C019AD40F /* GCCmds.h */; }; F5879BFC0195AF5C019AD40F /* GCdebug.h in Headers */ = {isa = PBXBuildFile; fileRef = F5879BF30195AF5C019AD40F /* GCdebug.h */; }; F5879BFD0195AF5C019AD40F /* GCUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = F5879BF50195AF5C019AD40F /* GCUtils.h */; }; F5879BFE0195AF5C019AD40F /* GemCore.h in Headers */ = {isa = PBXBuildFile; fileRef = F5879BF60195AF5C019AD40F /* GemCore.h */; }; F5879C010195AF5C019AD40F /* GCdebug.c in Sources */ = {isa = PBXBuildFile; fileRef = F5879BF20195AF5C019AD40F /* GCdebug.c */; }; F5879C020195AF5C019AD40F /* GCUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = F5879BF40195AF5C019AD40F /* GCUtils.c */; }; F5879C030195AF5C019AD40F /* ifdhandler.c in Sources */ = {isa = PBXBuildFile; fileRef = F5879BF70195AF5C019AD40F /* ifdhandler.c */; }; F5879C090195AFAD019AD40F /* GemPC430Utils.h in Headers */ = {isa = PBXBuildFile; fileRef = F5879C060195AFAD019AD40F /* GemPC430Utils.h */; }; F5879C0A0195AFAD019AD40F /* usbserial.h in Headers */ = {isa = PBXBuildFile; fileRef = F5879C080195AFAD019AD40F /* usbserial.h */; }; F5879C0B0195AFAD019AD40F /* GemPC430Utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F5879C040195AFAD019AD40F /* GemPC430Utils.c */; }; F5879C0C0195AFAD019AD40F /* GCUSBTransport.c in Sources */ = {isa = PBXBuildFile; fileRef = F5879C050195AFAD019AD40F /* GCUSBTransport.c */; }; F5879C0D0195AFAD019AD40F /* usbserial_mosx.c in Sources */ = {isa = PBXBuildFile; fileRef = F5879C070195AFAD019AD40F /* usbserial_mosx.c */; }; F5879C110195B3B3019AD40F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5879C0F0195B3B3019AD40F /* IOKit.framework */; }; F5879C160195B810019AD40F /* Config.h in Headers */ = {isa = PBXBuildFile; fileRef = F5879C150195B810019AD40F /* Config.h */; }; /* End PBXBuildFile section */ /* Begin PBXBundleTarget section */ 089C1673FE841209C02AAC07 /* ifd-GemPC430 */ = { isa = PBXBundleTarget; buildConfigurationList = 1FD8F2060F49A6FA0083CF66 /* Build configuration list for PBXBundleTarget "ifd-GemPC430" */; buildPhases = ( 089C1674FE841209C02AAC07 /* Headers */, 089C1675FE841209C02AAC07 /* Resources */, 089C1676FE841209C02AAC07 /* Sources */, 089C1677FE841209C02AAC07 /* Frameworks */, 089C1679FE841209C02AAC07 /* Rez */, ); dependencies = ( ); name = "ifd-GemPC430"; productInstallPath = "$(HOME)/Library/Bundles"; productName = "ifd-GemPC430"; productReference = 014CEA3E0018CDD111CA2923 /* ifd-GemPC430.bundle */; productSettingsXML = " CFBundleDevelopmentRegion English CFBundleExecutable ifd-GemPC430 CFBundleIconFile CFBundleIdentifier free.pcsc.GemPC430 CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType BNDL CFBundleSignature ???? CFBundleVersion 0.5.5 NSPrincipalClass 0x60000 ifdCapabilities 0x00000000 ifdFriendlyName GemPC430 ifdManufacturerString Gemplus ifdManufacturerURL http://www.gemplus.com/ ifdMaxSpeed 153600 ifdProductID 0x0430 ifdProductString GemPC430 ifdProtocolSupport 0x00000001 ifdReadTimeOut 60000 ifdVendorID 0x08E6 ifdVersionNumber 0x00000001 "; }; /* End PBXBundleTarget section */ /* Begin PBXFileReference section */ 014CEA3E0018CDD111CA2923 /* ifd-GemPC430.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = "ifd-GemPC430.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 1FD8F21A0F49A7AE0083CF66 /* ifdhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = ifdhandler.h; path = ../ifdhandler.h; sourceTree = SOURCE_ROOT; }; 1FD8F2250F49A8010083CF66 /* gempc_ifdhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gempc_ifdhandler.h; path = ../../common/gempc_ifdhandler.h; sourceTree = SOURCE_ROOT; }; 1FD8F23C0F49A86C0083CF66 /* debuglog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = debuglog.h; path = ../debuglog.h; sourceTree = SOURCE_ROOT; }; F5879BEE0195AEC8019AD40F /* GCCmds.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = GCCmds.c; path = ../../common/GCCmds.c; sourceTree = SOURCE_ROOT; }; F5879BF00195AF5C019AD40F /* GCTransport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GCTransport.h; path = ../../common/GCTransport.h; sourceTree = SOURCE_ROOT; }; F5879BF10195AF5C019AD40F /* GCCmds.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GCCmds.h; path = ../../common/GCCmds.h; sourceTree = SOURCE_ROOT; }; F5879BF20195AF5C019AD40F /* GCdebug.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = GCdebug.c; path = ../../common/GCdebug.c; sourceTree = SOURCE_ROOT; }; F5879BF30195AF5C019AD40F /* GCdebug.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GCdebug.h; path = ../../common/GCdebug.h; sourceTree = SOURCE_ROOT; }; F5879BF40195AF5C019AD40F /* GCUtils.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = GCUtils.c; path = ../../common/GCUtils.c; sourceTree = SOURCE_ROOT; }; F5879BF50195AF5C019AD40F /* GCUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GCUtils.h; path = ../../common/GCUtils.h; sourceTree = SOURCE_ROOT; }; F5879BF60195AF5C019AD40F /* GemCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = GemCore.h; path = ../../common/GemCore.h; sourceTree = SOURCE_ROOT; }; F5879BF70195AF5C019AD40F /* ifdhandler.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = ifdhandler.c; path = ../../common/ifdhandler.c; sourceTree = SOURCE_ROOT; }; F5879C040195AFAD019AD40F /* GemPC430Utils.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = GemPC430Utils.c; path = ../../GemPC430/GemPC430Utils.c; sourceTree = SOURCE_ROOT; }; F5879C050195AFAD019AD40F /* GCUSBTransport.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = GCUSBTransport.c; path = ../../GemPC430/GCUSBTransport.c; sourceTree = SOURCE_ROOT; }; F5879C060195AFAD019AD40F /* GemPC430Utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GemPC430Utils.h; path = ../../GemPC430/GemPC430Utils.h; sourceTree = SOURCE_ROOT; }; F5879C070195AFAD019AD40F /* usbserial_mosx.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = usbserial_mosx.c; path = ../../GemPC430/usbserial_mosx.c; sourceTree = SOURCE_ROOT; }; F5879C080195AFAD019AD40F /* usbserial.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = usbserial.h; path = ../../GemPC430/usbserial.h; sourceTree = SOURCE_ROOT; }; F5879C0F0195B3B3019AD40F /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; F5879C150195B810019AD40F /* Config.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Config.h; path = ../../GemPC430/Config.h; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 089C1677FE841209C02AAC07 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 0AA190A0FE8422F4C02AAC07 /* CoreFoundation.framework in Frameworks */, F5879C110195B3B3019AD40F /* IOKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 089C166AFE841209C02AAC07 /* ifd-GemPC430 */ = { isa = PBXGroup; children = ( 08FB77AFFE84173DC02AAC07 /* Source */, 089C167CFE841241C02AAC07 /* Resources */, 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, 19C28FB6FE9D52B211CA2CBB /* Products */, ); name = "ifd-GemPC430"; sourceTree = ""; }; 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( F5879C0F0195B3B3019AD40F /* IOKit.framework */, 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */, ); name = "External Frameworks and Libraries"; sourceTree = ""; }; 089C167CFE841241C02AAC07 /* Resources */ = { isa = PBXGroup; children = ( 089C167DFE841241C02AAC07 /* InfoPlist.strings */, ); name = Resources; sourceTree = ""; }; 08FB77AFFE84173DC02AAC07 /* Source */ = { isa = PBXGroup; children = ( 1FD8F23C0F49A86C0083CF66 /* debuglog.h */, 1FD8F2250F49A8010083CF66 /* gempc_ifdhandler.h */, 1FD8F21A0F49A7AE0083CF66 /* ifdhandler.h */, F5879C150195B810019AD40F /* Config.h */, F5879C040195AFAD019AD40F /* GemPC430Utils.c */, F5879C050195AFAD019AD40F /* GCUSBTransport.c */, F5879C060195AFAD019AD40F /* GemPC430Utils.h */, F5879C070195AFAD019AD40F /* usbserial_mosx.c */, F5879C080195AFAD019AD40F /* usbserial.h */, F5879BEE0195AEC8019AD40F /* GCCmds.c */, F5879BF00195AF5C019AD40F /* GCTransport.h */, F5879BF10195AF5C019AD40F /* GCCmds.h */, F5879BF20195AF5C019AD40F /* GCdebug.c */, F5879BF30195AF5C019AD40F /* GCdebug.h */, F5879BF40195AF5C019AD40F /* GCUtils.c */, F5879BF50195AF5C019AD40F /* GCUtils.h */, F5879BF60195AF5C019AD40F /* GemCore.h */, F5879BF70195AF5C019AD40F /* ifdhandler.c */, ); name = Source; sourceTree = ""; }; 19C28FB6FE9D52B211CA2CBB /* Products */ = { isa = PBXGroup; children = ( 014CEA3E0018CDD111CA2923 /* ifd-GemPC430.bundle */, ); name = Products; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 089C1674FE841209C02AAC07 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( F5879BFA0195AF5C019AD40F /* GCTransport.h in Headers */, F5879BFB0195AF5C019AD40F /* GCCmds.h in Headers */, F5879BFC0195AF5C019AD40F /* GCdebug.h in Headers */, F5879BFD0195AF5C019AD40F /* GCUtils.h in Headers */, F5879BFE0195AF5C019AD40F /* GemCore.h in Headers */, F5879C090195AFAD019AD40F /* GemPC430Utils.h in Headers */, F5879C0A0195AFAD019AD40F /* usbserial.h in Headers */, F5879C160195B810019AD40F /* Config.h in Headers */, 1FD8F21B0F49A7AE0083CF66 /* ifdhandler.h in Headers */, 1FD8F2260F49A8010083CF66 /* gempc_ifdhandler.h in Headers */, 1FD8F23D0F49A86C0083CF66 /* debuglog.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXProject section */ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1FD8F2050F49A6FA0083CF66 /* Build configuration list for PBXProject "ifd-GemPC430" */; compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 0; mainGroup = 089C166AFE841209C02AAC07 /* ifd-GemPC430 */; projectDirPath = ""; projectRoot = ..; targets = ( 089C1673FE841209C02AAC07 /* ifd-GemPC430 */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 089C1675FE841209C02AAC07 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 089C1680FE841241C02AAC07 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ 089C1679FE841209C02AAC07 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXRezBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 089C1676FE841209C02AAC07 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F5879BEF0195AEC8019AD40F /* GCCmds.c in Sources */, F5879C010195AF5C019AD40F /* GCdebug.c in Sources */, F5879C020195AF5C019AD40F /* GCUtils.c in Sources */, F5879C030195AF5C019AD40F /* ifdhandler.c in Sources */, F5879C0B0195AFAD019AD40F /* GemPC430Utils.c in Sources */, F5879C0C0195AFAD019AD40F /* GCUSBTransport.c in Sources */, F5879C0D0195AFAD019AD40F /* usbserial_mosx.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 089C167EFE841241C02AAC07 /* English */, ); name = InfoPlist.strings; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 1FD8F1FF0F49A6FA0083CF66 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Development; }; 1FD8F2000F49A6FA0083CF66 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Deployment; }; 1FD8F2010F49A6FA0083CF66 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Default; }; 1FD8F2020F49A6FA0083CF66 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/PCSC.framework/Headers\""; INSTALL_PATH = "$(HOME)/Library/Bundles"; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-O0"; OTHER_CFLAGS = ( "-DGEMPC=430", "-DRESPONSECODE_DEFINED_IN_WINTYPES_H", ); OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = "ifd-GemPC430"; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); WRAPPER_EXTENSION = bundle; ZERO_LINK = YES; }; name = Development; }; 1FD8F2030F49A6FA0083CF66 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/PCSC.framework/Headers\""; INSTALL_PATH = "$(HOME)/Library/Bundles"; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ( "-DGEMPC=430", "-DRESPONSECODE_DEFINED_IN_WINTYPES_H", ); OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = "ifd-GemPC430"; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); WRAPPER_EXTENSION = bundle; ZERO_LINK = NO; }; name = Deployment; }; 1FD8F2040F49A6FA0083CF66 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/PCSC.framework/Headers\""; INSTALL_PATH = "$(HOME)/Library/Bundles"; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ( "-DGEMPC=430", "-DRESPONSECODE_DEFINED_IN_WINTYPES_H", ); OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = "ifd-GemPC430"; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); WRAPPER_EXTENSION = bundle; }; name = Default; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1FD8F2050F49A6FA0083CF66 /* Build configuration list for PBXProject "ifd-GemPC430" */ = { isa = XCConfigurationList; buildConfigurations = ( 1FD8F1FF0F49A6FA0083CF66 /* Development */, 1FD8F2000F49A6FA0083CF66 /* Deployment */, 1FD8F2010F49A6FA0083CF66 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 1FD8F2060F49A6FA0083CF66 /* Build configuration list for PBXBundleTarget "ifd-GemPC430" */ = { isa = XCConfigurationList; buildConfigurations = ( 1FD8F2020F49A6FA0083CF66 /* Development */, 1FD8F2030F49A6FA0083CF66 /* Deployment */, 1FD8F2040F49A6FA0083CF66 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; /* End XCConfigurationList section */ }; rootObject = 089C1669FE841209C02AAC07 /* Project object */; } ifd-gempc-1.0.7/MacOSXbuild/ifdhandler.h0000644000175000017500000001333511146613225020241 0ustar rousseaurousseau/* * MUSCLE SmartCard Development ( http://www.linuxnet.com ) * * Copyright (C) 1999-2004 * David Corcoran * Damien Sauveron * * $Id: ifdhandler.h,v 1.1 2009-02-17 19:57:09 rousseau Exp $ */ /** * @file * @brief This provides reader specific low-level calls. */ #ifndef _ifd_handler_h_ #define _ifd_handler_h_ #include #include #ifdef __cplusplus extern "C" { #endif /* * List of data structures available to ifdhandler */ typedef struct _DEVICE_CAPABILITIES { LPSTR Vendor_Name; /**< Tag 0x0100 */ LPSTR IFD_Type; /**< Tag 0x0101 */ DWORD IFD_Version; /**< Tag 0x0102 */ LPSTR IFD_Serial; /**< Tag 0x0103 */ DWORD IFD_Channel_ID; /**< Tag 0x0110 */ DWORD Asynch_Supported; /**< Tag 0x0120 */ DWORD Default_Clock; /**< Tag 0x0121 */ DWORD Max_Clock; /**< Tag 0x0122 */ DWORD Default_Data_Rate; /**< Tag 0x0123 */ DWORD Max_Data_Rate; /**< Tag 0x0124 */ DWORD Max_IFSD; /**< Tag 0x0125 */ DWORD Synch_Supported; /**< Tag 0x0126 */ DWORD Power_Mgmt; /**< Tag 0x0131 */ DWORD Card_Auth_Devices; /**< Tag 0x0140 */ DWORD User_Auth_Device; /**< Tag 0x0142 */ DWORD Mechanics_Supported; /**< Tag 0x0150 */ DWORD Vendor_Features; /**< Tag 0x0180 - 0x01F0 User Defined. */ } DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES; typedef struct _ICC_STATE { UCHAR ICC_Presence; /**< Tag 0x0300 */ UCHAR ICC_Interface_Status; /**< Tag 0x0301 */ UCHAR ATR[MAX_ATR_SIZE]; /**< Tag 0x0303 */ UCHAR ICC_Type; /**< Tag 0x0304 */ } ICC_STATE, *PICC_STATE; typedef struct _PROTOCOL_OPTIONS { DWORD Protocol_Type; /**< Tag 0x0201 */ DWORD Current_Clock; /**< Tag 0x0202 */ DWORD Current_F; /**< Tag 0x0203 */ DWORD Current_D; /**< Tag 0x0204 */ DWORD Current_N; /**< Tag 0x0205 */ DWORD Current_W; /**< Tag 0x0206 */ DWORD Current_IFSC; /**< Tag 0x0207 */ DWORD Current_IFSD; /**< Tag 0x0208 */ DWORD Current_BWT; /**< Tag 0x0209 */ DWORD Current_CWT; /**< Tag 0x020A */ DWORD Current_EBC; /**< Tag 0x020B */ } PROTOCOL_OPTIONS, *PPROTOCOL_OPTIONS; typedef struct _SCARD_IO_HEADER { DWORD Protocol; DWORD Length; } SCARD_IO_HEADER, *PSCARD_IO_HEADER; /* * End of structure list */ /* * The list of tags should be alot more but this is all I use in the * meantime */ #define TAG_IFD_ATR 0x0303 #define TAG_IFD_SLOTNUM 0x0180 #define TAG_IFD_SLOT_THREAD_SAFE 0x0FAC #define TAG_IFD_THREAD_SAFE 0x0FAD #define TAG_IFD_SLOTS_NUMBER 0x0FAE #define TAG_IFD_SIMULTANEOUS_ACCESS 0x0FAF #define TAG_IFD_POLLING_THREAD 0x0FB0 #define TAG_IFD_POLLING_THREAD_KILLABLE 0x0FB1 /* * End of tag list */ /* * IFD Handler version number enummerations */ #define IFD_HVERSION_1_0 0x00010000 #define IFD_HVERSION_2_0 0x00020000 #define IFD_HVERSION_3_0 0x00030000 /* * End of version number enummerations */ /* * List of defines available to ifdhandler */ #define IFD_POWER_UP 500 #define IFD_POWER_DOWN 501 #define IFD_RESET 502 #define IFD_NEGOTIATE_PTS1 1 #define IFD_NEGOTIATE_PTS2 2 #define IFD_NEGOTIATE_PTS3 4 #define IFD_SUCCESS 0 #define IFD_ERROR_TAG 600 #define IFD_ERROR_SET_FAILURE 601 #define IFD_ERROR_VALUE_READ_ONLY 602 #define IFD_ERROR_PTS_FAILURE 605 #define IFD_ERROR_NOT_SUPPORTED 606 #define IFD_PROTOCOL_NOT_SUPPORTED 607 #define IFD_ERROR_POWER_ACTION 608 #define IFD_ERROR_SWALLOW 609 #define IFD_ERROR_EJECT 610 #define IFD_ERROR_CONFISCATE 611 #define IFD_COMMUNICATION_ERROR 612 #define IFD_RESPONSE_TIMEOUT 613 #define IFD_NOT_SUPPORTED 614 #define IFD_ICC_PRESENT 615 #define IFD_ICC_NOT_PRESENT 616 #define IFD_NO_SUCH_DEVICE 617 #ifndef RESPONSECODE_DEFINED_IN_WINTYPES_H typedef long RESPONSECODE; #endif /* * If you want to compile a V2.0 IFDHandler, define IFDHANDLERv2 before you * include this file. * * By default it is setup for for most recent version of the API (V3.0) */ #ifndef IFDHANDLERv2 /* * List of Defined Functions Available to IFD_Handler 3.0 * * All the functions of IFD_Handler 2.0 are available * IFDHCreateChannelByName() is new * IFDHControl() API changed */ RESPONSECODE IFDHCreateChannelByName(DWORD, LPSTR); RESPONSECODE IFDHControl(DWORD, DWORD, PUCHAR, DWORD, PUCHAR, DWORD, LPDWORD); #else /* * List of Defined Functions Available to IFD_Handler 2.0 */ RESPONSECODE IFDHControl(DWORD, PUCHAR, DWORD, PUCHAR, PDWORD); #endif /* * common functions in IFD_Handler 2.0 and 3.0 */ RESPONSECODE IFDHCreateChannel(DWORD, DWORD); RESPONSECODE IFDHCloseChannel(DWORD); RESPONSECODE IFDHGetCapabilities(DWORD, DWORD, PDWORD, PUCHAR); RESPONSECODE IFDHSetCapabilities(DWORD, DWORD, DWORD, PUCHAR); RESPONSECODE IFDHSetProtocolParameters(DWORD, DWORD, UCHAR, UCHAR, UCHAR, UCHAR); RESPONSECODE IFDHPowerICC(DWORD, DWORD, PUCHAR, PDWORD); RESPONSECODE IFDHTransmitToICC(DWORD, SCARD_IO_HEADER, PUCHAR, DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER); RESPONSECODE IFDHICCPresence(DWORD); /* * List of Defined Functions Available to IFD_Handler 1.0 */ RESPONSECODE IO_Create_Channel(DWORD); RESPONSECODE IO_Close_Channel(void); RESPONSECODE IFD_Get_Capabilities(DWORD, PUCHAR); RESPONSECODE IFD_Set_Capabilities(DWORD, PUCHAR); RESPONSECODE IFD_Set_Protocol_Parameters(DWORD, UCHAR, UCHAR, UCHAR, UCHAR); RESPONSECODE IFD_Power_ICC(DWORD); RESPONSECODE IFD_Swallow_ICC(void); RESPONSECODE IFD_Eject_ICC(void); RESPONSECODE IFD_Confiscate_ICC(void); RESPONSECODE IFD_Transmit_to_ICC(SCARD_IO_HEADER, PUCHAR, DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER); RESPONSECODE IFD_Is_ICC_Present(void); RESPONSECODE IFD_Is_ICC_Absent(void); #ifdef __cplusplus } #endif #endif ifd-gempc-1.0.7/GemPC410/0000755000175000017500000000000011740401711015024 5ustar rousseaurousseauifd-gempc-1.0.7/GemPC410/TODO.txt0000644000175000017500000000146611740361166016352 0ustar rousseaurousseauTODO list for GemPC410 ====================== - support memory cards DONE ==== - PowerUp 3V then if fails 5V - support more than one reader - create /dev/pcsc/[1-4] at module installation -> See README.410 - support hot unplug/replug (power off/on on the reader) -> should work if pcscd is restarted - do not reset the card if the command timeout -> the card is only reseted if the next command fails. The solution with long commands (and without sending time request bytes to the reader) is to wait a few seconds just after sending the long command (like a key generation on some Gemplus GPL cards) REJECTED ======== - support GCR400 or GCR410 it would be a hack on the common part. These readers are not sold anymore so support is not needed. $Id: TODO.txt,v 1.7 2012/04/08 19:09:42 rousseau Exp $ ifd-gempc-1.0.7/GemPC410/COPYING.GPL0000644000175000017500000004311010445301071016476 0ustar rousseaurousseau GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ifd-gempc-1.0.7/GemPC410/.dependencies0000644000175000017500000000000011740401711017441 0ustar rousseaurousseauifd-gempc-1.0.7/GemPC410/GCGBPTransport.c0000644000175000017500000001036311740361166017743 0ustar rousseaurousseau/* * GCGBPTransport.c: send a command to a GemCore serial reader Copyright * (C) 2001 Ludovic Rousseau * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * $Id: GCGBPTransport.c,v 1.10 2012/04/08 19:09:42 rousseau Exp $ * */ #include #include "Config.h" #include "GCdebug.h" #include "gempc_ifdhandler.h" #include "gbpserial.h" #include "GemCore.h" #include "GCTransport.h" /* * Transmission without errors: * Host Reader * I(0) -----------> * <----------- I(0) * I(1) -----------> * <----------- I(1) * * Transmission with errors * * Case 1: * Host Reader * I(0) -----/-----> * <----------- R(0) * I(0) -----------> * <----------- I(0) * * Case 2: * Host Reader * I(0) -----------> * <----\------ I(0) * R(0) -----------> * <----------- I(0) * I(1) -----------> * * Case 3: * Host Reader * I(0) -----/-----> * <----\------ R(0) * R(0) -----------> * <----------- R(0) * I(0) -----------> * <----------- I(0) * I(1) -----------> * * Case 4: * Host Reader * I(0) -----------> * <----\------ I(0) * R(0) -----/-----> * <----------- R(1) * R(0) -----------> * <----------- I(0) * I(1) -----------> * * Case 5: * Host Reader * I(0) -----------> * <----\------ I(0) * R(0) -----/-----> * <----\------ R(1) * R(0) -----------> * <----------- I(0) * I(1) -----------> * * Case 6: * Host Reader * I(0) -----------> * <----\------ I(0) * R(0) -----/-----> * <----\------ R(1) * R(0) -----/-----> * <----------- R(1) * R(0) -----------> * <----------- I(0) * I(1) -----------> * */ status_t GCSendCommand(DWORD Lun, DWORD nLengthIn, const UCHAR pcBufferCmd[], PDWORD pnLengthOut, PUCHAR pcBufferOut) { UCHAR pctr_to_card_buffer[GC_TR_BUF_SIZE]; RESPONSECODE creturn_value; DWORD nlength, rv; creturn_value = STATUS_SUCCESS; if (GC_TR_BUF_SIZE <= nLengthIn) { /* Buffer is too small (should not happen) */ creturn_value = STATUS_DEVICE_PROTOCOL_ERROR; goto finally; } again: memcpy(pctr_to_card_buffer + 1, pcBufferCmd, nLengthIn); pctr_to_card_buffer[TR_OFFSET_LNG] = nLengthIn; if (WriteGBP(Lun, nLengthIn + 1, pctr_to_card_buffer) != STATUS_SUCCESS) { creturn_value = STATUS_DEVICE_PROTOCOL_ERROR; goto finally; } nlength = sizeof(pctr_to_card_buffer); if ((rv = ReadGBP(Lun, &nlength, pctr_to_card_buffer)) != STATUS_SUCCESS) { /* The reader reports an error. */ /* Unknown NAD, retry the command */ if (rv == STATUS_NAD_UNKNOWN) { DEBUG_COMM("wrong NAD, resent sequence"); goto again; } /* resent sequence 0 */ if (rv == STATUS_PCB_REP_0) { DEBUG_COMM("resent sequence n°0"); SetGBPSeqNumber(Lun, 0); goto again; } /* resent sequence 1 */ if (rv == STATUS_PCB_REP_1) { DEBUG_COMM("resent sequence n°1"); SetGBPSeqNumber(Lun, 1); goto again; } if (rv == STATUS_PCB_SYNC_REQ || rv == STATUS_PCB_SYNC_RESP) { DEBUG_COMM("Resynch unsupported"); } creturn_value = STATUS_DEVICE_PROTOCOL_ERROR; goto finally; } if (nlength < 1) { /* length byte not received */ creturn_value = STATUS_DEVICE_PROTOCOL_ERROR; goto finally; } nlength--; *pnLengthOut = (*pnLengthOut < nlength) ? *pnLengthOut : nlength; memcpy(pcBufferOut, pctr_to_card_buffer + 1, *pnLengthOut); finally: if (creturn_value != STATUS_SUCCESS) *pnLengthOut = 0; /* Clear buffer */ bzero(pctr_to_card_buffer, sizeof(pctr_to_card_buffer)); return creturn_value; } /* GCSendCommand */ ifd-gempc-1.0.7/GemPC410/gbpserial.c0000644000175000017500000004721211740361166017157 0ustar rousseaurousseau/* * gbpserial.c: communicate with a GemPC410 smart card reader * using GemCore protocol * Copyright (C) 2001,2002 Ludovic Rousseau * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * $Id: gbpserial.c,v 1.43 2012/04/08 19:09:42 rousseau Exp $ */ #include #include #include #include #include #include #include #include #include #include "gempc_ifdhandler.h" #include "GemCore.h" #include "gbpserial.h" #include "Config.h" #include "GCdebug.h" #include "GCCmds.h" #include "GCUtils.h" /* * GBP (Gemplus Bloc Protocol) format * * +-----+-----+-----+---------+-----+ * | NAD | PCB | LEN | DAT ... | EDC | * +-----+-----+-----+---------+-----+ * * NAD: source and destination indentifier * PCB: block type * I-Block (Information) * bit 7 6 5 4-0 * +---+---+---+--------+ * | 0 | S | 0 | unused | * +---+---+---+--------+ * S = Sequence bit * * R-Block (Repeat) * bit 7 6 5 4 3 2 1 0 * +---+---+---+---+---+---+---+---+ * | 1 | 0 | 0 | S | 0 | 0 | E | V | * +---+---+---+---+---+---+---+---+ * V = Error verified by EDC * E = Another error * * S-Block (Synchro) * bit 7 6 5 4 3 2 1 0 * +---+---+---+---+---+---+---+---+ * | 1 | 1 | R | 0 | 0 | 0 | 0 | 0 | * +---+---+---+---+---+---+---+---+ * R = Resync * 0 = request * 1 = response * * LEN: number of bytes in DAT * DAT: data transmitted * EDC: xor on NAD, PCB, LEN and DAT bytes * */ /* indexes in GbpBuffer[] */ #define NAD 0 #define PCB 1 #define LEN 2 #define DAT 3 /* NAD values */ #define NAD_HOST2IFD 0x42 #define NAD_IFD2HOST 0x24 #define NAD_XXX2HOST 0x04 /* communication timeout in seconds */ #define SERIAL_TIMEOUT 60 /* * Global variables containing the file handle of the serial port */ typedef struct { char *device; int fd; signed char bSeq; } intrFace; #if (PCSCLITE_MAX_READERS-16) #error Edit this file and set the number of initialiser to PCSCLITE_MAX_READERS (default was 16 but it has changed) #endif static intrFace gbpDevice[PCSCLITE_MAX_READERS] = { [ 0 ... (PCSCLITE_MAX_READERS-1) ] = {NULL, -1, -1} }; /* complete buffer + 3 bytes used by GBP */ static UCHAR GbpBuffer[PCSCLITE_MAX_READERS][CMD_BUF_SIZE + 3]; int ExplainGBP(const unsigned char buffer[], const int rv); #define SetSerialSpeed(speed, bspeed, step) \ /* set OS speed to speed bauds */ \ cfsetspeed(¤t_termios, bspeed); \ \ DEBUG_INFO("Set serial port baudrate to " speed " (" step ")"); \ if (tcsetattr(gbpDevice[reader].fd, TCSANOW, ¤t_termios) == -1) \ { \ close(gbpDevice[reader].fd); \ gbpDevice[reader].fd = -1; \ DEBUG_INFO2("tcsetattr error: %s", strerror(errno)); \ \ return STATUS_UNSUCCESSFUL; \ } \ \ /* empty in and out serial buffers */ \ DEBUG_INFO("Flush serial buffers (" step ")"); \ if (tcflush(gbpDevice[reader].fd, TCIOFLUSH)) \ DEBUG_INFO2("tcflush() function error: %s", strerror(errno)); /***************************************************************************** * * WriteGBP: Send bytes to the card reader * * remark: buffer already contains the byte length in [0] * *****************************************************************************/ RESPONSECODE WriteGBP(DWORD lun, DWORD length, PUCHAR buffer) { int rv, len, i; UCHAR edc; int reader = LunToReaderIndex(lun); UCHAR *gbpbuffer = GbpBuffer[reader]; char debug_header[] = "-> 121234 "; sprintf(debug_header, "-> %06X ", (int)lun); /* PDU length = length + NAD + PCB + LEN */ len = length + 3; /* NAD byte */ gbpbuffer[NAD] = NAD_HOST2IFD; /* PCB byte */ gbpbuffer[PCB] = (gbpDevice[reader].bSeq << 6); /* copy LEN and DATA */ memcpy(gbpbuffer + LEN, buffer, length); /* checksum */ edc = 0; for (i = 0; i < len - 1; i++) edc ^= gbpbuffer[i]; /* EDC byte */ gbpbuffer[len - 1] = edc; /* increment Seq: 0 -> 1 or 1 -> 0 */ gbpDevice[reader].bSeq = (gbpDevice[reader].bSeq + 1) % 2; DEBUG_XXD(debug_header, gbpbuffer, len); rv = write(gbpDevice[reader].fd, gbpbuffer, len); if (rv < 0) { DEBUG_CRITICAL2("write error: %s", strerror(errno)); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; } /* WriteGBP */ /***************************************************************************** * * ReadGBP: Receive bytes from the card reader * * remark: buffer contains the byte length in [0] * *****************************************************************************/ RESPONSECODE ReadGBP(DWORD lun, PDWORD length, PUCHAR buffer) { int rv, len, to_read, already_read; int i, pcb, edc, hdr_processed; DWORD buffer_size; int reader = LunToReaderIndex(lun); UCHAR *gbpbuffer = GbpBuffer[reader]; fd_set fdset; int fd = gbpDevice[reader].fd; struct timeval t; char debug_header[] = "<- 121234 "; sprintf(debug_header, "<- %06X ", (int)lun); len = sizeof(GbpBuffer[reader]); buffer_size = *length; /* error by default */ *length = 0; /* We need at least 4 bytes */ to_read = 4; already_read = 0; hdr_processed = FALSE; /* Read loop */ while (already_read < to_read) { /* use select() to, eventually, timeout */ FD_ZERO(&fdset); FD_SET(fd, &fdset); t.tv_sec = SERIAL_TIMEOUT; t.tv_usec = 0; i = select(fd+1, &fdset, NULL, NULL, &t); if (i == -1) { DEBUG_CRITICAL2("select: %s", strerror(errno)); return STATUS_UNSUCCESSFUL; } else if (i == 0) { DEBUG_XXD(debug_header, gbpbuffer, already_read); DEBUG_COMM2("Timeout! (%d sec)", SERIAL_TIMEOUT); return STATUS_UNSUCCESSFUL; } rv = read(fd, gbpbuffer + already_read, len); if (rv < 0) { DEBUG_XXD(debug_header, gbpbuffer, already_read); DEBUG_COMM2("read error: %s", strerror(errno)); return STATUS_UNSUCCESSFUL; } already_read += rv; len -= rv; /* Process header if we just encountered it */ if ((already_read >= 4) && !hdr_processed) { /* NAD byte */ if ((gbpbuffer[NAD] != NAD_IFD2HOST) && (gbpbuffer[NAD] != NAD_XXX2HOST)) { DEBUG_XXD(debug_header, gbpbuffer, rv); ExplainGBP(gbpbuffer, rv); DEBUG_COMM2("wrong NAD byte 0x%02X", gbpbuffer[NAD]); return STATUS_NAD_UNKNOWN; } /* PCB byte */ pcb = gbpbuffer[PCB]; if (pcb & 0xA0) { int ret; DEBUG_XXD(debug_header, gbpbuffer, rv); ret = ExplainGBP(gbpbuffer, rv); DEBUG_COMM("PCB error"); return ret; } /* LEN byte (+4 bytes of protocol) */ to_read = gbpbuffer[LEN] + 4; /* Don't process header anymore */ hdr_processed = TRUE; } } /* calculate checksum */ edc = 0; for (i = 0; i < to_read; i++) edc ^= gbpbuffer[i]; DEBUG_XXD(debug_header, gbpbuffer, to_read); /* verify checksum */ if (edc != 0) { DEBUG_COMM("wrong EDC"); return STATUS_UNSUCCESSFUL; } /* copy up to buffer_size bytes */ if (buffer_size > gbpbuffer[LEN]) *length = gbpbuffer[LEN] + 1; else *length = buffer_size; memcpy(buffer, gbpbuffer + LEN, *length); return STATUS_SUCCESS; } /* ReadGBP */ /***************************************************************************** * * OpenGBP: open the port * *****************************************************************************/ RESPONSECODE OpenGBP(DWORD lun, LPSTR dev_name) { struct termios current_termios; int ospeed, i; int reader = LunToReaderIndex(lun); DEBUG_COMM3("Lun: %lX, device: %s", lun, dev_name); /* check if the same channel is not already used */ for (i=0; i 4) switch (buffer[3]) { case 0x00: DEBUG_COMM(" S: no error"); break; case 0x01: DEBUG_COMM(" S: unknown driver"); break; case 0x02: DEBUG_COMM(" S: operation impossible with this driver"); break; case 0x03: DEBUG_COMM(" S: incorrect number of arguments"); break; case 0x04: DEBUG_COMM(" S: reader command unknown"); break; case 0x05: DEBUG_COMM(" S: response too long for the buffer"); break; case 0x10: DEBUG_COMM(" S: resonse error at the card reset"); break; case 0x12: DEBUG_COMM(" S: message too long"); break; case 0x13: DEBUG_COMM(" S: byte reading error returned by an asynchronous cadr"); break; case 0x15: DEBUG_COMM(" S: card powered down"); break; case 0x1B: DEBUG_COMM(" S: a command has been sent with an incorrect number of parameters"); break; case 0x1C: DEBUG_COMM(" S: overlap on writing flash memory"); break; case 0x1D: DEBUG_COMM(" S: the TCK check byte is incorrect in a micropocessor card ATR"); break; case 0x1E: DEBUG_COMM(" S: an attempt has been made to write a write-protected external memory"); break; case 0x1F: DEBUG_COMM(" S: incorrect data has been send to external memory"); break; case 0xA0: DEBUG_COMM(" S: error in the card reset response"); break; case 0xA1: DEBUG_COMM(" S: card protocol error"); break; case 0xA2: DEBUG_COMM(" S: card malfuntion"); break; case 0xA3: DEBUG_COMM(" S: parity error"); break; case 0xA4: DEBUG_COMM(" S: card has been chaining (T=1)"); break; case 0xA5: DEBUG_COMM(" S: reader has aborted chaining (T=1)"); break; case 0xA6: DEBUG_COMM(" S: resynch successfully performed by GemCore"); break; case 0xA7: DEBUG_COMM(" S: protocol type selection (PTS) error"); break; case 0xB0: DEBUG_COMM(" S: GemCP410 command not supported"); break; case 0xCF: DEBUG_COMM(" S: other key already pressed"); break; case 0xE4: DEBUG_COMM(" S: the card has just send an invalid procedure byte"); break; case 0xE5: DEBUG_COMM(" S: the card has interrupted an exchange"); break; case 0xE7: DEBUG_COMM(" S: error returned by the card"); break; case 0xF7: DEBUG_COMM(" S: card removed"); break; case 0xF8: DEBUG_COMM(" S: the cadr is consuming too much electricity"); break; case 0xFB: DEBUG_COMM(" S: card missing"); break; default: DEBUG_COMM2(" S: UNKNOWN ERROR %02X", buffer[3]); break; } return ret; } /* ExplainGBP */ /***************************************************************************** * * ExplainGBP: print a textual error explanation * *****************************************************************************/ int SetGBPSeqNumber(DWORD lun, int seq) { int reader = LunToReaderIndex(lun); if (gbpDevice[reader].bSeq != -1) { gbpDevice[reader].bSeq = seq; return FALSE; } else return TRUE; } /* SetGBPSeqNumber */ ifd-gempc-1.0.7/GemPC410/GemPC410Utils.h0000644000175000017500000000075211740361166017413 0ustar rousseaurousseau/* * GemPC410Utils.h * $Id: GemPC410Utils.h,v 1.5 2012/04/08 19:09:42 rousseau Exp $ * GemPC410 dedicated functions * * Created by giraud on Sat Oct 20 2001. * Copyright (c) 2001-2004 Jean-Luc Giraud and Ludovic Rousseau * License: See file COPYING.GPL * */ #ifndef _GEMPC410UTILS_H_ #define _GEMPC410UTILS_H_ RESPONSECODE OpenGemPC410ByName(DWORD lun, LPSTR dev_name); RESPONSECODE OpenGemPC410(DWORD lun, DWORD channel); RESPONSECODE CloseGemPC410(DWORD lun); #endif ifd-gempc-1.0.7/GemPC410/resetGemPC410.c0000644000175000017500000002472011740401672017426 0ustar rousseaurousseau/* resetGemPC410 - try to debug the GBP comm Copyright (C) 2001 Ludovic Rousseau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * $Id: resetGemPC410.c,v 1.12 2012-02-14 21:09:14 rousseau Exp $ */ #include #include #include #include #include #include #define DEVICE "/dev/pcsc/2" #define BUFFER_SIZE 100 #define MAX_APDU_SIZE 16 void checksum(unsigned char cmd[], const int len); void debug(const unsigned char cmd[], const int len); void explain_gbp(const unsigned char buffer[], const int rv); int multi_read(int fd, unsigned char *buf, size_t count); int main(int argc, char *argv[]) { int fd; unsigned char cmd[MAX_APDU_SIZE], buffer[BUFFER_SIZE]; int rv; struct termios current_termios; (void)argc; (void)argv; printf("Using device: " DEVICE "\n"); if ((fd = open(DEVICE, O_RDWR | O_NOCTTY)) < 0) { printf("open error: %s\n", strerror(errno)); return 1; } if (tcgetattr(fd, ¤t_termios) == -1) { printf("tcgetattr() function error: %s\n", strerror(errno)); close(fd); fd = -1; return 1; } /* The serial port is not yet configured to 38400 bauds? */ if (cfgetospeed(¤t_termios) != B38400) { printf("actual baud rate: %d\n", cfgetospeed(¤t_termios)); current_termios.c_iflag = 0; current_termios.c_oflag = 0; /* Raw output modes */ current_termios.c_cflag = 0; /* Raw output modes */ /* Do not echo characters because if you connect * to a host it or your * modem will echo characters for you. * Don't generate signals. */ current_termios.c_lflag = 0; /* control flow - enable receiver - ignore modem * control lines */ current_termios.c_cflag = CREAD | CLOCAL; /* default speed is 38400 bauds */ cfsetospeed(¤t_termios, B38400); cfsetispeed(¤t_termios, 0); /* 0 corresponds to output speed */ current_termios.c_cflag |= CS8; /*case ODDPARITY: *current_termios.c_cflag |= PARENB + PARODD; *case EVENPARITY: *current_termios.c_cflag |= PARENB; * control caracteres * Minimum bytes to read * current_termios.c_cc[VMIN] = 0; * Time between two bytes read (VTIME x 0.10 s) * current_termios.c_cc[VTIME] = 0; * This is Non Canonical mode set. * by setting c_cc[VMIN]=0 and c_cc[VTIME] = 10 * each read operation will wait for 10/10 = 1 sec * If single byte is received, read function returns. * if timer expires, read() returns 0. * Minimum bytes to read */ current_termios.c_cc[VMIN] = 0; /* Time between two bytes read (VTIME x 0.10 s) */ current_termios.c_cc[VTIME] = 20; printf("Set serial port baudrate to 38400\n"); if (tcsetattr(fd, TCSANOW, ¤t_termios) == -1) { printf("tcsetattr error: %s\n", strerror(errno)); close(fd); fd = -1; return 1; } } else { printf("port " DEVICE " already at 38400 bauds\n"); } cmd[0] = 0x42; /* NAD */ cmd[1] = 0x00; /* PCB */ cmd[2] = 0x05; /* LEN */ cmd[3] = 0x22; /* Read Firmware Version */ cmd[4] = 0x05; cmd[5] = 0x3F; cmd[6] = 0xE0; cmd[7] = 0x10; cmd[8] = 0x00; /* EDC */ checksum(cmd, 9); printf("-> "); debug(cmd, 9); /* explain_gbp(cmd, 9); */ if (write(fd, cmd, 9) < 0) { printf("write error: %s\n", strerror(errno)); } if ((rv = multi_read(fd, buffer, BUFFER_SIZE)) < 0) { printf("read error: %s\n", strerror(errno)); } printf("%d bytes read\n<- ", rv); debug(buffer, rv); if (rv == 0) { if (tcgetattr(fd, ¤t_termios) == -1) { close(fd); fd = -1; printf("tcgetattr() function error\n"); return 1; } current_termios.c_cflag = CREAD | CLOCAL; /* default speed is 9600 bauds */ current_termios.c_cflag |= B9600; current_termios.c_cflag |= CS8; printf("Set serial port baudrate to 9600\n"); if (tcsetattr(fd, TCSANOW, ¤t_termios) == -1) { close(fd); fd = -1; printf("tcsetattr error"); return 1; } } explain_gbp(buffer, rv); cmd[1] = 0x40; checksum(cmd, 9); printf("-> "); debug(cmd, 9); /* explain_gbp(cmd, 9); */ if (write(fd, cmd, 9) < 0) { printf("write error: %s\n", strerror(errno)); } if ((rv = multi_read(fd, buffer, BUFFER_SIZE)) < 0) { printf("read error: %s\n", strerror(errno)); } printf("%d bytes read\n<- ", rv); debug(buffer, rv); explain_gbp(buffer, rv); /* reset GemCore */ cmd[0] = 0x42; /* NAD */ cmd[1] = 0x00; /* PCB */ cmd[2] = 0x04; /* LEN */ cmd[3] = 0x0C; /* Restart */ cmd[4] = 0x00; cmd[5] = 0x00; cmd[6] = 0x00; cmd[7] = 0x00; /* EDC */ checksum(cmd, 8); printf("-> "); debug(cmd, 8); if (write(fd, cmd, 8) < 0) { printf("write error: %s\n", strerror(errno)); } if ((rv = multi_read(fd, buffer, BUFFER_SIZE)) < 0) { printf("read error: %s\n", strerror(errno)); } printf("%d bytes read\n<- ", rv); debug(buffer, rv); explain_gbp(buffer, rv); close(fd); return 0; } /* main */ void checksum(unsigned char cmd[], const int len) { int edc, i; /* checksum */ edc = 0; for (i=0; i 31) printf("%c", cmd[i]); else printf("."); printf("\n"); } /* debug */ void explain_gbp(const unsigned char buffer[], const int rv) { if (rv < 4) { printf("GBP bloc too short: %d instead of min 5\n", rv); return; } switch (buffer[0]) { case 0x42: printf(" NAD: host to gemcore\n"); break; case 0x24: printf(" NAD: gemcore to host\n"); break; default: printf(" NAD: UNKNOWN value %02X\n", buffer[0]); } switch (buffer[1]) { case 0x00: printf(" PCB: I-block S=0\n"); break; case 0x40: printf(" PCB: I-block S=1\n"); break; case 0x80: printf(" PCB: R-block S=0, EDC error=0, another error=0\n"); break; case 0x90: printf(" PCB: R-block S=1, EDC error=0, another error=0\n"); break; case 0x81: printf(" PCB: R-block S=0, EDC error=1, another error=0\n"); break; case 0x91: printf(" PCB: R-block S=1, EDC error=1, another error=0\n"); break; case 0x82: printf(" PCB: R-block S=0, EDC error=0, another error=1\n"); break; case 0x92: printf(" PCB: R-block S=1, EDC error=0, another error=1\n"); break; case 0x83: printf(" PCB: R-block S=0, EDC error=1, another error=1\n"); break; case 0x93: printf(" PCB: R-block S=1, EDC error=1, another error=1\n"); break; case 0xB0: printf(" PCB: S-block resynch request\n"); break; case 0xE0: printf(" PCB: S-block resynch response\n"); break; default: printf(" PCB: UNKNOWN value %02X\n", buffer[1]); break; } printf(" LEN: %02X bytes\n", buffer[2]); switch (buffer[3]) { case 0x00: printf(" S: no error\n"); break; case 0x01: printf(" S: unknown driver\n"); break; case 0x02: printf(" S: operation impossible with this driver\n"); break; case 0x03: printf(" S: incorrect number of arguments\n"); break; case 0x04: printf(" S: reader command unknown\n"); break; case 0x05: printf(" S: response too long for the buffer\n"); break; case 0x10: printf(" S: resonse error at the card reset\n"); break; case 0x12: printf(" S: message too long\n"); break; case 0x13: printf(" S: byte reading error returned by an asynchronous cadr\n"); break; case 0x15: printf(" S: card powered down\n"); break; case 0x1B: printf(" S: a command has been sent with an incorrect number of parameters\n"); break; case 0x1C: printf(" S: overlap on writing flash memory\n"); break; case 0x1D: printf(" S: the TCK check byte is incorrect in a micropocessor card ATR\n"); break; case 0x1E: printf(" S: an attempt has been made to write a write-protected external memory\n"); break; case 0x1F: printf(" S: incorrect data has been send to external memory\n"); break; case 0xA0: printf(" S: error in the card reset response\n"); break; case 0xA1: printf(" S: card protocol error\n"); break; case 0xA2: printf(" S: card malfuntion\n"); break; case 0xA3: printf(" S: parity error\n"); break; case 0xA4: printf(" S: card has been chaining (T=1)\n"); break; case 0xA5: printf(" S: reader has aborted chaining (T=1)\n"); break; case 0xA6: printf(" S: resynch successfully performed by GemCore\n"); break; case 0xA7: printf(" S: protocol type selection (PTS) error\n"); break; case 0xB0: printf(" S: GemCP410 command not supported\n"); break; case 0xCF: printf(" S: other key already pressed\n"); break; case 0xE4: printf(" S: the card has just send an invalid procedure byte\n"); break; case 0xE5: printf(" S: the card has interrupted an exchange\n"); break; case 0xE7: printf(" S: error returned by the card\n"); break; case 0xF7: printf(" S: card removed\n"); break; case 0xF8: printf(" S: the cadr is consuming too much electricity\n"); break; case 0xFB: printf(" S: card missing\n"); break; default: printf(" S: UNKNOWN ERROR %02X\n", buffer[3]); break; } return; } /* explain_gbp */ int multi_read(int fd, unsigned char *buf, size_t count) { int rv, len, to_read, already_read; rv = read(fd, buf, count); if (rv < 0) return rv; /* too short */ if (rv < 3) { printf("ReadGBP: only %d byte(s) read\n", rv); return rv; } /* LEN byte (+4 bytes of protocol) */ to_read = buf[2]+4; /* Nb of bytes already read */ already_read = rv; /* Nb of bytes until the end of the buffer */ len = count - rv; while (already_read < to_read) { rv = read(fd, buf+already_read, len); if (rv < 0) { printf("ReadGBP: read error: %s\n", strerror(errno)); return rv; } already_read += rv; len -= rv; } return to_read; } /* multi_read */ ifd-gempc-1.0.7/GemPC410/GemPC410Utils.c0000644000175000017500000000362211740361166017405 0ustar rousseaurousseau/* * GemPC410Utils.c * $Id: GemPC410Utils.c,v 1.13 2012/04/08 19:09:42 rousseau Exp $ * GemPC410 dedicated functions * * Created by giraud on Sat Oct 20 2001. * Modified by Ludovic Rousseau , Nov 2001 * Copyright (c) 2001 Jean-Luc Giraud and Ludovic Rousseau * License: See file COPYING.GPL * */ #include #include "gempc_ifdhandler.h" #include "GemCore.h" #include "Config.h" #include "GemPC410Utils.h" #include "GCCmds.h" #include "gbpserial.h" #include "GCdebug.h" #include "GCTransport.h" RESPONSECODE OpenGemPC410ByName(DWORD lun, LPSTR dev_name) { UCHAR os_version[IFD_LEN_VERSION + 2]; DWORD length; if (OpenGBP(lun, dev_name) != STATUS_SUCCESS) { DEBUG_CRITICAL("OpenGBP failed"); return IFD_COMMUNICATION_ERROR; } /* Get the GemCore OS version */ length = sizeof(os_version); if (GCCmdGetOSVersion(lun, &length, os_version) != IFD_SUCCESS) { DEBUG_CRITICAL("GCCmdGetOSVersion failed"); return IFD_COMMUNICATION_ERROR; } DEBUG_CRITICAL2("OS string: %s", os_version); /* Set the mode to ROS but no TLP (ATR should then be fine) */ if (GCCmdSetMode(lun, IFD_MODE_ROSNOTLP) != IFD_SUCCESS) { DEBUG_CRITICAL("Setmode failed"); CloseGBP(lun); return IFD_COMMUNICATION_ERROR; } return IFD_SUCCESS; } /* OpenGemPC410ByName */ RESPONSECODE OpenGemPC410(DWORD lun, DWORD channel) { char dev_name[FILENAME_MAX]; /* * Conversion of old-style ifd-hanler 1.0 CHANNELID */ if (channel == 0x0103F8) channel = 1; else if (channel == 0x0102F8) channel = 2; else if (channel == 0x0103E8) channel = 3; else if (channel == 0x0102E8) channel = 4; sprintf(dev_name, "/dev/pcsc/%d", (int) channel); return OpenGemPC410ByName(lun, dev_name); } /* OpenGemPC410 */ RESPONSECODE CloseGemPC410(DWORD lun) { if (CloseGBP(lun) != STATUS_SUCCESS) return IFD_COMMUNICATION_ERROR; return IFD_SUCCESS; } /* CloseGemPC410 */ ifd-gempc-1.0.7/GemPC410/gbpserial.h0000644000175000017500000000121210561621324017145 0ustar rousseaurousseau/* Title: gbpserial.h / Author: Ludovic Rousseau / Copyright: 2001, GNU General Public Licence / Purpose: Abstracts GBP API to serial like calls */ /* #define STATUS_PCB_ERROR 0xFE */ #define STATUS_PCB_REP_0 0x1000 #define STATUS_PCB_REP_1 0x1001 #define STATUS_PCB_SYNC_REQ 0x1002 #define STATUS_PCB_SYNC_RESP 0x1003 #define STATUS_NAD_UNKNOWN 0x1004 RESPONSECODE OpenGBP(DWORD lun, LPSTR dev_name); RESPONSECODE WriteGBP(DWORD lun, DWORD length, unsigned char *Buffer); RESPONSECODE ReadGBP(DWORD lun, unsigned long *length, unsigned char *Buffer); RESPONSECODE CloseGBP(DWORD lun); int SetGBPSeqNumber(DWORD lun, int seq); ifd-gempc-1.0.7/GemPC410/Config.h0000644000175000017500000000120610561621066016410 0ustar rousseaurousseau/* * $Id: Config.h,v 1.12 2005-06-17 10:37:38 rousseau Exp $ * ifd-GemPC410 * * Created by JL Giraud on Sun Nov 19 2000. * Updated by Ludovic Rousseau Nov 23 2001. * License: See file COPYING.GPL * */ #ifndef __CONFIG_H__ #define __CONFIG_H__ /* Perform automatic PPS negociation * unsed by default for safety instead of speed */ /* #define AUTOMATIC_PPS */ /* GemPC410 specific */ #define OpenPort OpenGemPC410 #define OpenPortByName OpenGemPC410ByName #define ClosePort CloseGemPC410 #define ReadPort ReadGBP #define WritePort WriteGBP #define READER_NAME "GemPC41x" #endif ifd-gempc-1.0.7/GemPC410/Makefile0000644000175000017500000000371611740361517016504 0ustar rousseaurousseau# # $Id: Makefile,v 1.53 2012/04/08 19:13:19 rousseau Exp $ # # set this path to where you installed pcsc-lite INCS = `pkg-config libpcsclite --cflags` INSTALL_DIR = $(DESTDIR)`pkg-config libpcsclite --variable=usbdropdir`/serial # use a correct default CFLAGS ifeq ($(CFLAGS),) CFLAGS = -O2 -g -Wall -fPIC -I. -I../common -DGEMPC=410 $(INCS) else CFLAGS += -Wall -fPIC -I. -I../common -DGEMPC=410 $(INCS) endif # /home/rousseau/sc/pcsc/i/ifd-gempc-0.5.10/GemPC410 -> 0.5.10 version=$(shell expr `pwd` : '.*-\([0-9.]*\)') targets = GCGBPTransport.o gbpserial.o GemPC410Utils.o common_targets = ../common/ifdhandler.o ../common/GCCmds.o ../common/GCUtils.o all: check expert check: check_stamp check_stamp: CFLAGS="$(INCS)" ../check 410 touch check_stamp expert: ifd-GemPC410 resetGemPC410 libGemPC410.so common: $(MAKE) -C ../common CFLAGS="$(CFLAGS) -I../GemPC410" all ifd-GemPC410: common $(targets) main.o ../common/GCdebug.o $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(targets) $(common_targets) main.o ../common/GCdebug.o resetGemPC410: resetGemPC410.o $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ libGemPC410.so: common $(targets) rm -f $@ $(CC) -shared $(CFLAGS) $(LDFLAGS) $(targets) $(common_targets) -o $@ chmod -x $@ mv $@ $@.$(version) clean: rm -f .dependencies touch .dependencies rm -f $(targets) rm -f ifd-GemPC410 main.o rm -f libGemPC410.so* rm -f resetGemPC410.o resetGemPC410 $(MAKE) -C ../common clean rm -f Makefile.bak rm -f config.log distclean: clean rm -f tags rm -f check_stamp dep_stamp install: all if [ ! -d $(INSTALL_DIR) ] ; then install -d $(INSTALL_DIR) ; fi cp -R libGemPC410.so.$(version) $(INSTALL_DIR) dep: dep_stamp dep_stamp: @echo "Making dependencies..." makedepend -f - -I. -I../common -DGEMPC=410 *.c > .dependencies || true $(MAKE) -C ../common dep touch dep_stamp .dependencies: dep ctags: ctags-exuberant *.h *.c ../common/*.h ../common/*.c .PHONY: all common clean distclean dep ctags expert check include .dependencies ifd-gempc-1.0.7/GemPC410/main.c0000644000175000017500000001323611740361166016132 0ustar rousseaurousseau/* main.c: main function used for IFDH debug Copyright (C) 2001-2004 Ludovic Rousseau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * $Id: main.c,v 1.21 2012/04/08 19:09:42 rousseau Exp $ */ #include #include #include #include #include "gempc_ifdhandler.h" #include "Config.h" #include "GCdebug.h" /* CHANNELID: / 0x000001 - /dev/pcsc/1 / 0x000002 - /dev/pcsc/2 / 0x000003 - /dev/pcsc/3 / 0x000004 - /dev/pcsc/4 */ /* 1 -> GCR400 / 2 -> GemPC410 */ #define SERIAL_PORT 2 #define SERIAL_NAME "/dev/pcsc/2" /* for the GemPC430 use something like usb:08e6/0430 */ #define LUN 0 void pcsc_error(int rv); int main(int argc, char *argv[]) { int rv, i, len_i, len_o; UCHAR atr[MAX_ATR_SIZE]; DWORD atrlength; UCHAR s[MAX_BUFFER_SIZE], r[MAX_BUFFER_SIZE]; DWORD dwSendLength, dwRecvLength; SCARD_IO_HEADER SendPci, RecvPci; if (argc > 0) rv = IFDHCreateChannelByName(LUN, argv[1]); else rv = IFDHCreateChannelByName(LUN, SERIAL_NAME); if (rv != IFD_SUCCESS) { printf("IFDHCreateChannel: %d\n", rv); return 1; } #if 0 rv = IFDHCreateChannel(LUN, SERIAL_PORT); if (rv != IFD_SUCCESS) { printf("IFDHCreateChannel: %d\n", rv); return 1; } #endif rv = IFDHICCPresence(LUN); pcsc_error(rv); rv = IFDHPowerICC(LUN, IFD_RESET, atr, &atrlength); if (rv != IFD_SUCCESS) { printf("IFDHPowerICC: %d\n", rv); goto end; } DEBUG_XXD("ATR: ", atr, atrlength); rv = IFDHICCPresence(LUN); pcsc_error(rv); memset(&SendPci, 0, sizeof(SendPci)); memset(&RecvPci, 0, sizeof(RecvPci)); /* select applet */ s[0] = 0x00; s[1] = 0xA4; s[2] = 0x04; s[3] = 0x00; s[4] = 0x06; s[5] = 0xA0; s[6] = 0x00; s[7] = 0x00; s[8] = 0x00; s[9] = 0x18; s[10] = 0xFF; dwSendLength = 11; dwRecvLength = sizeof(r); DEBUG_XXD("Select applet: ", s, dwSendLength); rv = IFDHTransmitToICC(LUN, SendPci, s, dwSendLength, r, &dwRecvLength, &RecvPci); DEBUG_XXD("Received: ", r, dwRecvLength); if (rv) pcsc_error(rv); /* Case 1 */ s[0] = 0x80; s[1] = 0x21; s[2] = 0x00; s[3] = 0x00; s[4] = 0x00; dwSendLength = 5; dwRecvLength = sizeof(r); DEBUG_XXD("Case 1: ", s, dwSendLength); rv = IFDHTransmitToICC(LUN, SendPci, s, dwSendLength, r, &dwRecvLength, &RecvPci); DEBUG_XXD("Received: ", r, dwRecvLength); if (rv) pcsc_error(rv); /* Case 2 */ /* * 248 (0xF8) is max size for one USB or GBP paquet * 255 (0xFF) maximum, 1 minimum */ len_i = 255; s[0] = 0x80; s[1] = 0x22; s[2] = 0x00; s[3] = 0x00; s[4] = len_i; for (i=0; i 255) { s[2] = 0x01; s[3] = len_o-256; } else { s[2] = 0x00; s[3] = len_o; } s[4] = len_o; dwSendLength = 5; dwRecvLength = sizeof(r); DEBUG_XXD("Case 3: ", s, dwSendLength); rv = IFDHTransmitToICC(LUN, SendPci, s, dwSendLength, r, &dwRecvLength, &RecvPci); DEBUG_XXD("Received: ", r, dwRecvLength); if (rv) pcsc_error(rv); /* Case 4 */ /* * len_i * 248 (0xF8) is max size for one USB or GBP paquet * 255 (0xFF) maximum, 1 minimum * * len_o * 252 (0xFC) is max size for one USB or GBP paquet * 256 (0x100) maximum, 1 minimum */ len_i = 255; len_o = 256; s[0] = 0x80; s[1] = 0x24; if (len_o > 255) { s[2] = 0x01; s[3] = len_o-256; } else { s[2] = 0x00; s[3] = len_o; } s[4] = len_i; for (i=0; i * README: Release 1.0.7 * GemPC430/Makefile, GemPC410/Makefile: Use CFLAGS and LDFLAGS Fix Debian bug #667931 * GemPC410/GCGBPTransport.c, GemPC410/GemPC410Utils.c, GemPC410/GemPC410Utils.h, GemPC410/Makefile, GemPC410/TODO.txt, GemPC410/gbpserial.c, GemPC410/main.c, GemPC430/GCUSBTransport.c, GemPC430/libusb_wrap.c, GemPC430/usbserial_mosx.c, common/GCUtils.c, common/GCdebug.c, common/GCdebug.h, common/GemCore.h, common/ifdhandler.c: Remove extra spaces * GemPC430/usbserial.h, GemPC430/usbserial_mosx.c: Use status_t insteaf of gcore_t when needed GCUSBTransport.c: In function ‘GCSendCommand’: GCUSBTransport.c:40:57: attention : comparison between ‘gcore_t’ and ‘enum ’ [-Wenum-compare] GCUSBTransport.c:47:53: attention : comparison between ‘gcore_t’ and ‘enum ’ [-Wenum-compare] * GemPC430/libusb_wrap.c: Fix compiler warnings libusb_wrap.c: In function ‘OpenUSB’: libusb_wrap.c:93:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] libusb_wrap.c:129:3: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] * GemPC410/GemPC410Utils.c: Remove dead code GemPC410Utils.c: In function ‘OpenGemPC410’: GemPC410Utils.c:74:2: attention : comparaison d'une expression non signée < 0 est toujours fausse [-Wtype-limits] * GemPC410/gbpserial.c: Fix compiler warning gbpserial.c: In function ‘OpenGBP’: gbpserial.c:328:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] * common/GCUtils.c: Remove dead code GCUtils.c: In function ‘iLunCheck’: GCUtils.c:46:3: attention : comparaison d'une expression non signée < 0 est toujours fausse [-Wtype-limits] * common/GCdebug.c: Fix compiler warnings ../common/GCdebug.c: In function ‘log_msg’: ../common/GCdebug.c:22:24: attention : unused parameter ‘priority’ [-Wunused-parameter] ../common/GCdebug.c: In function ‘log_xxd’: ../common/GCdebug.c:33:24: attention : unused parameter ‘priority’ [-Wunused-parameter] * common/ifdhandler.c: Use %lX and %ld for DWORD types ifdhandler.c: In function ‘IFDHCreateChannelByName’: ifdhandler.c:51:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] ifdhandler.c: In function ‘IFDHCreateChannel’: ifdhandler.c:113:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] ifdhandler.c:113:2: attention : format ‘%d’ expects argument of type ‘int’, but argument 7 has type ‘DWORD’ [-Wformat] ifdhandler.c: In function ‘IFDHCloseChannel’: ifdhandler.c:149:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] ifdhandler.c: In function ‘IFDHGetCapabilities’: ifdhandler.c:184:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] ifdhandler.c:184:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 7 has type ‘DWORD’ [-Wformat] ifdhandler.c: In function ‘IFDHSetCapabilities’: ifdhandler.c:240:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] ifdhandler.c:240:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 7 has type ‘DWORD’ [-Wformat] ifdhandler.c: In function ‘IFDHSetProtocolParameters’: ifdhandler.c:269:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] ifdhandler.c: In function ‘IFDHPowerICC’: ifdhandler.c:326:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] ifdhandler.c: In function ‘IFDHTransmitToICC’: ifdhandler.c:421:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] ifdhandler.c: In function ‘IFDHControl’: ifdhandler.c:557:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] ifdhandler.c: In function ‘IFDHICCPresence’: ifdhandler.c:585:2: attention : format ‘%X’ expects argument of type ‘unsigned int’, but argument 6 has type ‘DWORD’ [-Wformat] * common/GCCmds.c: Remove unused variable 2012-02-14 Ludovic Rousseau * GemPC410/gbpserial.c, GemPC410/resetGemPC410.c: Fix typo writting -> writing 2010-09-03 Ludovic Rousseau * GemPC430/50-pcscd-ifd-gempc.rules: udev rules to set the access rights of GemPC smart card readers so they can be used by pcscd 2010-06-16 Ludovic Rousseau * README: release 1.0.6 * GemPC410/gbpserial.c: OpenGBP(): and null fd is valid. Only negative values are errors. Thanks to Joerg Hartenberger for the patch 2010-01-03 Ludovic Rousseau * common/GCCmds.c: GCCmdSetMode(): fix a spelling error 2009-04-12 Ludovic Rousseau * README: release 1.0.5 * GemPC410/resetGemPC410.c: remove "unused parameter" warnings * common/ifdhandler.c, GemPC430/GemPC430Utils.c: remove "unused parameter" warning * common/ifdhandler.c: remove "unused parameter" warnings * common/GCCmds.c: GCCmds.c:481: attention : assignment discards qualifiers from pointer target type * GemPC430/Makefile, GemPC410/Makefile: correctly manage LDFLAGS Thanks to Arfrever Frehtes Taifersar Arahesis for the patch 2009-02-18 Ludovic Rousseau * MacOSXbuild/ifd-GemPC430/ifd-GemPC430.xcodeproj/project.pbxproj: add X Code 2 project * MANIFEST: remove build/ files 2009-02-17 Ludovic Rousseau * MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/categories.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/decls.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/files.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/imports.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/pbxindex.header, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/protocols.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/refs.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/strings.pbxstrings/control, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/strings.pbxstrings/strings, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/subclasses.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/symbols0.pbxsymbols, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.indexed-headers, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.indexed-precomps: useless files * MANIFEST, MacOSXbuild/ifd-GemPC430/ifd-GemPC430.pbproj/giraud.pbxuser, MacOSXbuild/ifd-GemPC430/ifd-GemPC430.pbproj/project.pbxproj: use X Code v2 project * MANIFEST: add MacOSXbuild/debuglog.h and MacOSXbuild/ifdhandler.h * common/GCdebug.h, common/GemCore.h, GemPC430/usbserial_mosx.c, MacOSXbuild/debuglog.h, MacOSXbuild/ifdhandler.h: allow build on Mac OS X using X Code 2008-10-15 Ludovic Rousseau * README: release 1.0.4 * common/GCCmds.c: Fix powerup sequence when switching to ISO mode If somehow the reader/card was in EMV mode, we need to switch it to ISO. This was done but the final attemp to powerup tried to power it up in EMV mode ... most likely a typo. Patch from Sylvain Munaut * README: release 1.0.4 * GemPC410/gbpserial.c: Allow the header to be read in several calls Previously, if the header was not read in a single read() calls, there was an error. This is an issue because some commands return the two first bytes, then a small pause, then the rest of the header ... At least this happens on a gci410emv connected thru an usb adapter ... Now it works fine. Patch from Sylvain Munaut 2007-08-14 Ludovic Rousseau * README: release 1.0.3 * common/GCCmds.c: GCCmdGetOSVersion(): correct a big bug unnoticed for many years and declared on PowerPC with gcc 4.x (Debian bug #428323) * GemPC410/Makefile, GemPC430/Makefile: do not strip the library so we have debug symbols if needed. strip should be called by the package build process (if needed) * common/GCCmds.c: GCGemCoreError(): log only is text is non NULL 2007-06-29 Ludovic Rousseau * README: release 1.0.2 * common/GCCmds.c: correctly handle empty response from the reader. Thanks to Thomas Galliano for the bug report * GemPC430/Makefile, GemPC410/Makefile: do not set DESTDIR if not defined 2007-02-05 Ludovic Rousseau * GemPC430/libusb_wrap.c: correctly initialise usbDevice[] * common/ifdhandler.c, GemPC410/GemPC410Utils.c, GemPC410/GemPC410Utils.h, GemPC410/gbpserial.c, GemPC410/gbpserial.h, GemPC430/GemPC430Utils.c, GemPC430/GemPC430Utils.h, GemPC430/libusb_wrap.c, GemPC430/libusb_wrap.h: LPTSTR -> LPSTR since LPTSTR is deprecated 2006-02-09 Ludovic Rousseau * README: release 1.0.1 * GemPC430/libusb_wrap.c, common/GCdebug.c, common/ifdhandler.c: fix some compilation warnings with gcc 4.0 * check: allow compilation with pcsc-lite-1.2.9-beta10. The script was buggy for beta > 9 * GemPC430/libusb_wrap.c: WriteUSB(): remove a useless "POUET" debug message 2005-06-17 Ludovic Rousseau * GemPC430/libusb_wrap.c: define interface, bulk_in and bulk_out fields and store the device values. We need to store them because the libusb structures are now half destroyed when the device is removed. * README: release 1.0.0 * GemPC430/Makefile: use `pkg-config libpcsclite --variable=usbdropdir` to know where to install the driver * GemPC410/Makefile: use `pkg-config libpcsclite --variable=usbdropdir` to know where to install the library * GemPC410/Makefile: remove definition of version_major * GemPC410/Makefile: do not create symbolic links anymore for *.so and *.so.major * check: require 1.2.9-beta7 instead of 1.2.9-beta5 * GemPC410/main.c: replace debug_xxd() by DEBUG_XXD() * GemPC410/main.c: the device name can be passed as the command line argument * GemPC410/gbpserial.c, GemPC430/libusb_wrap.c: remove every #ifdef DEBUG_LEVEL_* * GemPC410/Config.h, GemPC430/Config.h: remove the DEBUG_LEVEL_* definition since we use the dynamic log level of log_msg() * common/GCCmds.c: GCGemCoreError(): use log_msg() instead of debug_msg() * common/GCCmds.c: GCMakeCommand(): set the error code to no error by default if the device disapear the output buffer is not filled so no GemCore error is returned * common/GCdebug.c: define log_msg()/log_xxd() instead of debug_msg()/debug_xxd() * common/GCdebug.h: use Log1?() from PCSC/debuglog.h 2004-08-08 Ludovic Rousseau * README: release 0.9.3 * common/GCCmds.c, common/GCCmds.h: use const attribute when needed * GemPC430/libusb_wrap.h: *USB functions return status_t and not gcore_t 2004-07-24 Ludovic Rousseau * README: release 0.9.2 * check: minium pcsc-lite version is now 1.2.9-beta5 * check: update the URL where new pcsc-lite archives can be fetched * common/ifdhandler.c: change IFDHControl() API to conform to pcsc-lite 1.2.9-beta5 2004-07-03 Ludovic Rousseau * GemPC410/Config.h, GemPC410/GCGBPTransport.c, GemPC410/GemPC410Utils.c, GemPC410/gbpserial.h, GemPC410/main.c, GemPC410/resetGemPC410.c, GemPC430/Config.h, GemPC430/GCUSBTransport.c, GemPC430/GemPC430Utils.c, common/GCCmds.c, common/GCTransport.h, common/GCUtils.c, common/GCUtils.h, common/GemCore.h, common/ifdhandler.c: use C comments /* */ instead of C++ // * MANIFEST: remove common/{ifdhandler.h,pcscdefines.h,winscard.h,wintypes.h} add common/gempc_ifdhandler.h * GemPC410/GemPC410Utils.c, GemPC430/libusb_wrap.c, GemPC410/GemPC410Utils.h, GemPC410/gbpserial.c, GemPC410/gbpserial.h, GemPC430/GemPC430Utils.c, GemPC430/GemPC430Utils.h, GemPC430/libusb_wrap.h: LPSTR -> LPTSTR * GemPC410/GCGBPTransport.c, GemPC410/GemPC410Utils.c, GemPC410/gbpserial.c, GemPC410/main.c, GemPC430/GCUSBTransport.c, GemPC430/GemPC430Utils.c, GemPC430/libusb_wrap.c: use #include "gempc_ifdhandler.h" * GemPC410/Makefile, GemPC430/Makefile: add `pkg-config libpcsclite --cflags` to INCS * common/GCCmds.c, common/GCUtils.c, common/GemCore.h, common/gempc_ifdhandler.h, common/ifdhandler.c: define PCSCLITE_MAX_READERS * common/gempc_ifdhandler.h: GemPC specific declarations * common/ifdhandler.h, common/pcscdefines.h, common/winscard.h, common/wintypes.h: removed since we now used the one provided by pcsc-lite * check: check for pcsclite.h instead of PCSC/pcsclite.h but use CHECK_CFLAGS=`pkg-config libpcsclite --cflags` * check: check for PCSC/pcsclite.h instead of pcsclite.h 2004-03-24 Ludovic Rousseau * GemPC410/Makefile: define default DESTDIR as /usr/local instead of /usr/local/pcsc/drivers/serial. Thanks to Daniel Black for the patch. 2004-02-27 Ludovic Rousseau * README: release 0.9.1 * common/GCCmds.c, common/GCUtils.c: use new GCGemCoreError() format * common/GCCmds.h: add char *file, int line, char *function arguments to GCGemCoreError() * common/GCdebug.h: add DEBUG_CRITICAL4 * GemPC430/libusb_wrap.c: use pcsc-lite new IFDHCreateChannelByName() scheme: usb:vendor/product * GemPC410/Config.h, GemPC430/Config.h, common/GCCmds.c: use AUTOMATIC_PPS instead of NO_AUTO_PPS and do not define by default for safety instead of speed 2004-02-25 Ludovic Rousseau * GemPC430/TODO.txt: move some old items from todo to done * GemPC410/Config.h, GemPC430/Config.h: Add definition of NO_AUTO_PPS (commented) * common/GCCmds.c: do not perform automatic PPS negiciation by the reader firmware if NO_AUTO_PPS is defined (some cards need this) 2004-02-21 Ludovic Rousseau * common/GCCmds.c, common/GemCore.h: add "Card powered down" 0x15 GemCore error 2004-02-07 Ludovic Rousseau * common/GCCmds.c: Do not print the '"Error" returned by the card' message to avoid confusion * common/GCCmds.c: add message for GCORE_INVALID_PROC_BYTE (0xE4) 2004-02-02 Ludovic Rousseau * common/pcscdefines.h: remove white spaces before #define to avoid gcc-Version 3.3.2 20031022 warnings. Thanks to Toni Andjelkovic for the patch 2004-01-22 Ludovic Rousseau * README: release 0.9.0 * GemPC410/TODO.txt: support of 3V-5V and "more than one reader" are now present * README: latest pcsc-lite are available from alioth now 2004-01-20 Ludovic Rousseau * MANIFEST: remove GemPC410/devfs/ files * GemPC410/devfs/README, GemPC410/devfs/libgempc410.conf.d, GemPC410/devfs/libgempc410.devfsd.conf, GemPC410/devfs/libgempc410.devices.d: no devfs problems with /dev/pcsc/ is no more used. * README.410: /dev/pcsc/ is deprecated and DEVICENAME should be used instead of CHANNELID with recent pcsc-lite versions (> 1.2.0) * GemPC410/Makefile: default installation directory is now /usr/local/pcsc/drivers/serial instead of /usr/local/lib * GemPC430/libusb_wrap.c: remove debug printf * MANIFEST: rename GemPC410/TODO in GemPC410/TODO.txt to be consistant with GemPC430/TODO.txt * GemPC430/libusb_wrap.c: add missing #endif * GemPC410/gbpserial.c, GemPC430/libusb_wrap.c, GemPC430/usbserial_mosx.c, common/GCCmds.c, common/GCUtils.c, common/GCdebug.h, common/ifdhandler.c: remove function name from DEBUG_* calls * GemPC430/Config.h, GemPC430/GemPC430Utils.c, GemPC430/GemPC430Utils.h, GemPC430/libusb_wrap.c, GemPC430/libusb_wrap.h, common/ifdhandler.c, common/ifdhandler.h, GemPC410/Config.h, GemPC410/GemPC410Utils.c, GemPC410/GemPC410Utils.h, GemPC410/gbpserial.c, GemPC410/gbpserial.h, GemPC410/main.c: add support of IFDHCreateChannelByName() * common/GCdebug.h: add __FUNCTION__ in DEBUG_* messages 2004-01-19 Ludovic Rousseau * GemPC430/libusb_wrap.c: use asymetric timeout for USB read and write. The reader/card may be busy when we read (long timeout) but should be OK when we write (short timeout) 2003-12-15 Ludovic Rousseau * GemPC410/gbpserial.c: use C instead of C++ comments * GemPC430/libusb_wrap.c: reset the reader in case of timeout on write (reader freeze?). Thanks to Patrick Valsecchi for the patch. 2003-10-27 Ludovic Rousseau * GemPC430/usbserial_mosx.c: typo: changed PCSCLITE_MAX_RERADERS to PCSCLITE_MAX_READERS. Thanks to Jakob Schlyter for the patch. 2003-10-22 Ludovic Rousseau * README: release 0.8.2 * GemPC410/Makefile: create $(DESTDIR) only if does not exist yet * common/GCUtils.c, common/ifdhandler.c: Remove support for multi slot. The code was never used and is now broken under revent pcsc-lite versions. * common/GCCmds.c, common/GemCore.h: add support for CARD_T1_ABORT, READER_T1_ABORT, RESYNC, PTS and INVALID_PROC_BYTE GemCore errors * GemPC410/Makefile: use $(DESTDIR) instead of $(DESTDIR)/lib/ * check: Explain how to tell check to look elsewhere than just /usr/ and /usr/local/ 2003-09-07 Ludovic Rousseau * common/GCCmds.c, common/GemCore.h: add 0x10 and 0xF7 GemCore error codes 2003-09-05 Ludovic Rousseau * README: release 0.8.1 * GemPC410/gbpserial.c: set serial timeout to 1 minute 2003-09-02 Ludovic Rousseau * MANIFEST: removed common/pcsclite.h * GemPC410/gbpserial.c, GemPC430/libusb_wrap.c, GemPC430/usbserial_mosx.c, common/GCUtils.c, common/ifdhandler.c, common/pcscdefines.h: use PCSCLITE_MAX_READERS instead of PCSCLITE_MAX_CHANNELS (as introduced in pcsc-lite-1.2.0-rc1) * common/pcsclite.h: useless file. defines are in pcscdefines.h * MANIFEST: move Info.plist from GemPC430/ifd-GemPC430.bundle/Contents/ to GemPC430/ * GemPC430/libusb_wrap.c: use a->b notation instead of a[0].b * common/GCCmds.c, common/GemCore.h: add support of GemCore "Parity error during exchange" * GemPC410/Makefile, GemPC430/Makefile, check: check uses paths defined in Makefile * GemPC410/devfs/libgempc410.devfsd.conf: use $devpath instead of $devname otherwise we have /dev/pcsc/1 -> tts/0 2003-08-20 Ludovic Rousseau * GemPC430/Info.plist: use new style 2003-08-18 Ludovic Rousseau * GemPC430/usbserial_mosx.c: remove \n in debug messages since they are not needed 2003-08-14 Ludovic Rousseau * GemPC410/Makefile, GemPC430/Makefile, common/Makefile: do not exit with failure if makedepend(1) does not exist 2003-08-08 Ludovic Rousseau * common/GCCmds.c: Error and not Errror * common/GCCmds.c: Add " " around Error message when the SW is not 9000. * README.410: add a note about DEVICENAME in /etc/reader.conf 2003-08-07 Ludovic Rousseau * MacOSXbuild/ifd-GemPC430/English.lproj/InfoPlist.strings, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/symbols0.pbxsymbols, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.indexed-headers, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/subclasses.pbxbtree: These files were not commited in CVS * GemPC430/Makefile: do not remove ifd-GemPC430.bundle/Contents/Linux anymore since this directory is no more created * GemPC430/Makefile: do not use a intermediary ifd-GemPC430.bundle directory, copy all needed file to $DESTDIR directly * GemPC410/Makefile, GemPC430/Makefile, common/Makefile: update (again) the build of files in common/ * common/ifdhandler.c: FDHGetCapabilities() add support of tag TAG_IFD_SLOTS_NUMBER 2003-06-04 Ludovic Rousseau * GemPC430/Makefile: remove ifd-GemPC430.bundle/Contents/Linux in distclean 2003-05-03 Ludovic Rousseau * Makefile: clean/distclean common _after_ GemPC410 and GemPC430 * common/Makefile, GemPC410/Makefile, GemPC430/Makefile: remove *_stamp in distclean and not clean rules 2003-04-12 Ludovic Rousseau * README: release 0.8.0 * README.410: small typos * README.430: small typo * Makefile: remove config.log in distclean * GemPC430/Makefile, GemPC430/Info.plist: library name is versionned (libGemPC430.so.0.8.0) * GemPC410/Makefile, GemPC430/Makefile: remove rule to build version for an old pcsc-lite * GemPC410/Makefile, GemPC430/Makefile: optimize common rule (use common_stamp to avoid unnecessary recompilation) * GemPC410/Makefile, GemPC430/Makefile, common/Makefile: avoid running dep and check rules each time (use stamp files) 2003-04-06 Ludovic Rousseau * GemPC410/main.c: do all the tests (removed goto) * common/ifdhandler.h: add prototype for IFDSetEmv() * GemPC430/Makefile: remove installation of multiple drivers since alias is supported * GemPC430/Info.plist: add alias names 2003-03-30 Ludovic Rousseau * common/GCCmds.c, common/GemCore.h, common/ifdhandler.c: add support for EMV mode * common/GCUtils.c: use function GCGemCoreError() in gemcore_status_processing() * common/GCCmds.c, common/GCCmds.h: add function GCGemCoreError() * common/GCCmds.c: Add support of GemCore 2000 Power Up used by GemPC413 * common/GemCore.h: add 3 new error codes * GemPC410/main.c: use debug_xxd() and DEBUG_INFO() 2003-03-21 Ludovic Rousseau * GemPC410/Config.h, GemPC430/Config.h, common/GCdebug.c: remove debug using syslog (pcscd logs where needed to be) 2003-03-19 Ludovic Rousseau * common/pcsclite.h: sync with version from pcsc-lite 1.1.2beta3 2003-03-14 Ludovic Rousseau * GemPC430/libusb_wrap.c: change USB timeout from 10 to 60 seconds 2003-03-13 Ludovic Rousseau * check: do not use /usr/local/include by default since cpp will warning on some systems 2002-11-26 Ludovic Rousseau * GemPC410/Makefile, GemPC430/Makefile: do not force use of -O2 -g if CFLAGS is already defined 2002-11-20 Ludovic Rousseau * README: release 0.7.4 * MANIFEST: add check file * Makefile: remove removing of config.log in clean rule since it is unneeded here * GemPC410/Makefile, GemPC430/Makefile: remove config.log in clean rule * GemPC410/gbpserial.c: on arm, powerpc and s390 "char" is unsigned by default. So use an explicit "signed char". Thank to Gerhard Tonn for looking at Debian autobuilder logs. * README.430: add comment on how to compile the USB driver (install libusb, etc.) * GemPC430/Makefile, GemPC410/Makefile, Makefile: add support of the ./check script * check: script used to test the correct version of pcsc-lite and libusb 2002-10-18 Ludovic Rousseau * README: release 0.7.3 * GemPC430/libusb_wrap.c: support hotplug _after_ pcscd is started. 2002-10-15 Ludovic Rousseau * README: release 0.7.2 * GemPC410/gbpserial.c: rename variable fd_set to fdset to avoid a name clash with structure fd_set * README: release 0.7.1 * GemPC410/gbpserial.c: add #include * GemPC410/main.c: add #include * GemPC410/Makefile, GemPC430/Makefile, common/Makefile: remove CC=gcc definition 2002-10-13 Ludovic Rousseau * README: add comment about makedepend(1) * README: add comment about devfs * README: release 0.7.0 * MacOSXbuild/ifd-GemPC430/ifd-GemPC430.pbproj/giraud.pbxuser, MacOSXbuild/ifd-GemPC430/ifd-GemPC430.pbproj/project.pbxproj: new version * GemPC430/usbserial_mosx.c: - better stability and multiple reader support - the productId is now read from the Info.plist. This allow to support readers like the 432 and 435 without recompiling the library 2002-10-10 Ludovic Rousseau * GemPC430/usblinux.c, GemPC430/usblinux.h, GemPC430/usbserial_linux.c: Removed. Replaced by libusb_wrap.c and libusb_wrap.h * GemPC430/README.Linux: Removed. See README.430 instead * GemPC430/libusb_wrap.c: test dev->config != NULL before accessing the structure * GemPC410/Makefile, GemPC430/Makefile, MANIFEST, common/Makefile: do not remove but empty .dependencies files in clean and distclean rules. We need the makedepend(1) command to regenerate these files and this command comes with XFree which is not installed on console only systems. * GemPC410/gbpserial.c: use select() instead of termios.c_cc[VTIME] = 100 to timeout since it did not worked under FreeBSD * README.410: FreeBSD (4.7-RC2) and OpenBSD (3.1) do not use the same name for the serial port devices 2002-10-09 Ludovic Rousseau * GemPC430/Makefile: add /usr/local/include and /usr/local/lib paths needed when libusb is installed in /usr/local/ * common/Makefile, GemPC410/Makefile, GemPC430/Makefile: do not remove .dependencies files since makedepend(1) is not installed by default. 2002-10-06 Ludovic Rousseau * GemPC410/Makefile: avoid GNU options in cp(1) and install(1). Some Unix systems are not GNU. * GemPC430/libusb_wrap.c: lots of debug * GemPC430/Makefile: link the driver against libusb * GemPC410/main.c: shutdown the driver before exiting even if no card is present 2002-10-03 Ludovic Rousseau * common/ifdhandler.c: - add lun in log info - completely remove unused and buggy mutex use (the driver shall be reentrant) * GemPC410/gbpserial.c: - add channel information in open device structure to detect a double usage - log Lun in low level input/output logs - use one buffer per reader (instead of a global one) to be reentrant - optimise the open port in case Host and IFD both at 38400 bauds already (normal case for a pcscd restart on Linux) 2002-09-27 Ludovic Rousseau * GemPC430/Makefile, GemPC430/libusb_wrap.c, GemPC430/libusb_wrap.h: port to libusb library 2002-09-26 Ludovic Rousseau * common/ifdhandler.c: start support of multi reader: add mutex to avoid race problems * GemPC430/Makefile, GemPC430/usbserial_linux.c: start support for more than one reader with the same library * GemPC410/Makefile, GemPC410/gbpserial.c: add support for more than one reader with the same library * README.430: add a section on USB support under Linux 2002-09-22 Ludovic Rousseau * GemPC410/TODO.txt: do not reset the card if the command timeout: DONE, a workaround is given * GemPC410/devfs/README, GemPC410/devfs/libgempc410.conf.d, GemPC410/devfs/libgempc410.devfsd.conf, GemPC410/devfs/libgempc410.devices.d, README.410: add devfsd configuration files in devfs/ and support in README.410 2002-09-18 Ludovic Rousseau * README.430: add a note about /proc/bus/usb/ directory under Linux * GemPC410/TODO.txt: The GCR400 and GCR410 will NOT be supported. So removed from the TODO list. * common/GCCmds.c, common/GemCore.h: add "Incorrect number of arguments" GemCore error message * GemPC410/GCGBPTransport.c, GemPC410/gbpserial.c, GemPC410/gbpserial.h: retry the last command if GBP returns a wrong first byte (NAD) 2002-09-08 Ludovic Rousseau * GemPC410/gbpserial.c: use the simpler GCCmdSetMode command instead of GCCmdCardStatus * GemPC410/gbpserial.c: use a SetSerialSpeed macro to factorise code. Add debug messages even when the OpenGBP() returns OK to know what init branch was taken. * GemPC410/GCGBPTransport.c: sequence 0 -> sequence n°0 * GemPC410/resetGemPC410.c: PCB of reset command was wrong 2002-09-07 Ludovic Rousseau * GemPC410/GCGBPTransport.c, GemPC410/gbpserial.c, GemPC410/gbpserial.h: add support for GemCore Repeat requests * common/GCdebug.h: file Config.h not included -> file Config.h NOT included * GemPC410/Config.h: comment DEBUG_LEVEL_PERIODIC and DEBUG_LEVEL_COMM * create_distrib.sh: add test to avoid releasing a version with too much DEBUG on 2002-08-16 Ludovic Rousseau * GemPC430/Makefile: change libGemPC430 to libGemPC430.so * common/GCdebug.c: moved from GemPC410 * common/GCdebug.c: removed * README: release 0.6.5 * GemPC410/Makefile, GemPC430/Makefile: correct clean rule to take care of _old_pcscd versions * GemPC430/Makefile: add old_pcscd and libGemPC430_old_pcscd rules * GemPC410/Makefile: add old_pcscd and libGemPC410_old_pcscd.so rules * GemPC410/Makefile, GemPC430/Makefile, common/Makefile: GCdebug.c is now in common/ again * Makefile: rewrote install rule * GemPC410/gbpserial.c: hacked again the initialisation. It did not work since: the GCCmdConfigureSIOLine will OFTEN fails since the GemCore response is sent using the NEW speed but GCMakeCommand do not know how to handle this. * GemPC410/main.c: removed Log history * GemPC410/TODO.txt: "create /dev/pcsc/[1-4]" and "support hot unplug/replug" mark done "do not reset the card if the command timeout" added * GemPC410/Config.h, GemPC430/Config.h: renamed GemPC410 to GemPC41x and GemPC430 to GemPC43x add DEBUG_SYSLOG #define (undefined by default) 2002-08-13 Ludovic Rousseau * GemPC410/Makefile, GemPC430/Makefile: remove GCdebug.o in clean rule * GemPC430/Makefile, GemPC410/Makefile: install in /usr/local by default * common/ifdhandler.c: do not debug APDU. This is done by pcscd now * common/GCdebug.h, common/Makefile: now use the debug facilities from pcscd * common/GCCmds.c: repagination of comments 2002-08-12 Ludovic Rousseau * GemPC410/resetGemPC410.c: add a reset GemCore call * GemPC410/gbpserial.c: add state name in the OpenGBP() error messages * GemPC410/Makefile: do not link the driver with GCdebug.o since we now use the debug functions of pcscd * GemPC430/Makefile, GemPC430/usbserial_linux.c: support for 432 and 435 readers * GemPC410/Config.h, GemPC430/Config.h: remove DEBUG_LEVEL_APDU and DEBUG_STDERR since we now use pcscd debug functions 2002-08-02 Ludovic Rousseau * GemPC430/usbserial_linux.c: add support for more than one reader add support for GemPC 435 2002-08-01 Ludovic Rousseau * GemPC410/Makefile, GemPC430/Makefile: add an "all" dependency in the "install" target (thanks Joe Phillips) 2002-07-31 Ludovic Rousseau * GemPC410/Makefile: create destination directory in install rule * Makefile: add make install target 2002-05-23 Ludovic Rousseau * README: release 0.6.4 2002-05-21 Ludovic Rousseau * GemPC410/main.c: exit if powerup fails * common/GCCmds.c: perform a powerup without PPS managment is the powerup with PPS managment failed * GemPC410/resetGemPC410.c: minimum size for a GBP bloc is 4 bytes and not 5 * GemPC410/main.c: add an error message 2002-05-19 Ludovic Rousseau * GemPC430/Makefile, common/Makefile: add -f to rm .dependencies * GemPC410/gbpserial.c, GemPC410/resetGemPC410.c: change sys_errlist[errno] to strerror(errno) to be (more) ready for the Hurd * GemPC410/Makefile: add -f to rm .dependencies * GemPC430/usbserial_linux.c: print comm debug messages only if DEBUG_LEVEL_COMM is defined * GemPC430/Makefile, common/Makefile: correctly remove .dependencies file 2002-05-09 Ludovic Rousseau * README: release 0.6.3 * common/ifdhandler.c: Case1 APDU now uses a (null length) ISO IN instead of ISO OUT * common/GCUtils.c: case nlength==0 in ISO_INPUT is used for Case1 APDUs * README.410: Add info on /dev/pcsc/ for OpenBSD and FreeBSD 2002-04-03 Ludovic Rousseau * GemPC410/main.c: clear SendPci and RecvPci structures before use add IFD_PROTOCOL_NOT_SUPPORTED error case * GemPC410/gbpserial.c: changed cfsetospeed() and cfsetispeed() to one cfsetspeed() * GemPC410/Makefile: libGemPC410.so rule: remove target before creation (needed to avoid loops under OpenBSD) 2002-04-01 Ludovic Rousseau * README: release 0.6.2 * MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.indexed-precomps, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/decls.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/files.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/imports.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/pbxindex.header, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/refs.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/strings.pbxstrings/control, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/strings.pbxstrings/strings: new version of build files * MANIFEST: add file MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.indexed-headers * GemPC430/usbserial_mosx.c: Fixes for multi-reader support * common/GCCmds.c: GCCmdPowerUp() power up with auto PPS management * common/ifdhandler.c, common/ifdhandler.h: add case TAG_IFD_SIMULTANEOUS_ACCESS in IFDHGetCapabilities() * GemPC410/gbpserial.c: complete reimplementation of serial port configuration correct treatment when IFD send a 0x04 instead of a 0x24 (NAD_IFD2HOST) * create_distrib.sh: make distclean defore archiving * GemPC410/Makefile, GemPC430/Makefile, Makefile, common/Makefile: add distclean rule in all Makefiles * MacOSXbuild/ifd-GemPC430/ifd-GemPC430.pbproj/giraud.pbxuser, MacOSXbuild/ifd-GemPC430/ifd-GemPC430.pbproj/project.pbxproj: new files in CVS 2002-03-27 Ludovic Rousseau * GemPC410/Makefile, common/Makefile: correct make dep rule * common/GCCmds.c: GCCmdSetMode() returns OK when GemCore answers GCORE_UNKNOWN_CMD since the command is disabled when ROS mode is disabled (native only). * GemPC410/gbpserial.c: remove debug printf() changed %02X to 0x%02X 2002-03-11 Ludovic Rousseau * README: release 0.6.1 * GemPC410/gbpserial.c: changed again the serial port opening 2002-03-07 Ludovic Rousseau * README: release 0.6.0 * GemPC410/.dependencies: removed * GemPC410/Makefile: clean rule: remove Makefile.bak .dependencies * common/Makefile: clean rule: remove tags file * common/ifdhandler.c: forgot a closing } * common/ifdhandler.c: Debug in IFDHSetCapabilities and IFDHICCPresence is now PERIODIC IFDHTransmitToICC: now manage case 1 APDU (only CLA, INS, P1, P2) as an outgoing APDU (CLA, INS, P1, P2, 0) * common/GCdebug.h: add DEBUG_PERIODIC definitions * common/GCCmds.c: Debug in GCCmdCardStatus is now PERIODIC * GemPC410/gbpserial.c: rewrote the serial port BAUDS setting during open() * GemPC410/Config.h, GemPC430/Config.h: document log levels add new log level: DEBUG_LEVEL_PERIODIC 2002-03-05 Ludovic Rousseau * common/GCUtils.c: replaced 2 by the equivalent constant ISO_SIZE_SW 2002-03-03 Ludovic Rousseau * README: release 0.5.10 * GemPC410/main.c: add hexa values of max length add a new test (commented by default) * GemPC410/Makefile: add -f in 'ln -s' to avoid error if the link already exist * common/GCUtils.c: Correct a bug when more than 252 output bytes are expected and less than that are available (which is the case when the card sends an error) * common/GCCmds.c: add command options for IFD_CMD_ICC_POWER_UP disable PPS management (needed by some kinds of Cyberflex Access cards) * GemPC410/Makefile: modify install: rule to include release version number in filename, create symlinks, remove execution right on the .so lib * GemPC410/main.c: changed default serial port 2002-02-16 Ludovic Rousseau * README.410: Add a script to create the /dev/pcsc/? links * GemPC410/.dependencies, GemPC410/Makefile: change the way compilation dependencies are generated and stored 2001-12-09 Ludovic Rousseau * GemPC410/GemPC410Utils.c, GemPC430/GemPC430Utils.c, common/GCCmds.c: guarantee that the os_string is \0 terminated 2001-12-06 Ludovic Rousseau * GemPC410/resetGemPC410.c, GemPC410/gbpserial.c: use cfgetospeed()/cfsetospeed() instead of accessing directly the termios structure 2001-12-04 Ludovic Rousseau * create_distrib.sh: support direcory names containing numbers and not just digits (add a \+ to the sed pattern matching) 2001-12-02 Ludovic Rousseau * common/ifdhandler.c: also log APDU results * GemPC410/gbpserial.c: changed DEBUG_COMM to DEBUG_LEVEL_COMM 2001-12-01 Ludovic Rousseau * GemPC430/Config.h: revert to just "#define foo" instead of "#define foo 1" * GemPC410/GemPC410Utils.c, GemPC430/GemPC430Utils.c: avoid a non NULL terminated string on the GemCore version string 2001-11-30 Ludovic Rousseau * README: release 0.5.9 * MANIFEST: add ProjectBuilder folder for MacOS X * MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/categories.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/decls.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/files.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/imports.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/pbxindex.header, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/protocols.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/refs.pbxbtree, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/strings.pbxstrings/control, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.pbxindex/strings.pbxstrings/strings, MacOSXbuild/ifd-GemPC430/build/intermediates/ifd-GemPC430.indexed-precomps: added ProjectBuilder folder for MacOS X * common/GCUtils.c: change an IFD_SUCCESS to STATUS_SUCCESS * GemPC430/usbserial_mosx.c: add #include "GemCore.h" 2001-11-27 Ludovic Rousseau * README: release 0.5.8 * create_distrib.sh: do not exclude create_distrib.sh remove temporary directory at exit (including by Ctrl-C) * MANIFEST: include create_distrib.sh * create_distrib.sh: correct first line to be #!/bin/bash instead of #/bin/sh * MANIFEST, README: removed GemPC430/main.c since the file does not exist anymore * GemPC410/GCGBPTransport.h: unsued and then deleted * create_distrib.sh: add -p to mkdir to also create parent directory if it does not exist * MANIFEST: removed deleted files * README: release 0.5.7 * GemPC430/ifd-GemPC430.pbproj/giraud.pbxuser, GemPC430/ifd-GemPC430.pbproj/project.pbxproj, GemPC430/English.lproj/InfoPlist.strings: Useless file (not distributed in the archive) * common/GCUtils.c: change return test from IFD_SUCCESS to STATUS_SUCCESS * GemPC410/Makefile: removed automatically generated depends lines * GemPC430/usblinux.c: closedir() only if the device is found and usable (write access) the code crashed with two USB readers * GemPC410/Makefile, GemPC410/main.c: Implement ISO 7816 Case 2, 3 and 4 with full length tests * GemPC410/main.c: add a pcsc_error() function instead of code duplication add ReaderTest (Java test applet) APDU for ISO 7816 Case 1 * GemPC410/resetGemPC410.c: print more error messages * GemPC410/gbpserial.c: "OpenGBP" instead of "OpenUSB" print error message in case of tcgetattr() fails * common/GCUtils.c: add support for IFD_ICC_NOT_PRESENT GemCore error status 2001-11-24 Ludovic Rousseau * GemPC410/gbpserial.c: prepare to support multi serial reader * GemPC430/usbserial_mosx.c: remove \n in log messages and change %08x to 0x%08X * GemPC430/usbserial_mosx.c: use TRUE & FALSE instead of 1 & 0 * GemPC430/usbserial_linux.c: use USB_TIMEOUT #define instead of 10000 * GemPC430/usbserial_linux.c: prepare support for multi USB readers * common/GCdebug.h: add DEBUG_COMM3() * GemPC410/gbpserial.c: do not limit to 4 readers anymore (accept channel >= 4) 2001-11-23 Ludovic Rousseau * common/GCCmds.c: add #include 2001-11-22 Ludovic Rousseau * GemPC410/gbpserial.c: removed $Log$ * GemPC410/GCGBPTransport.c, GemPC410/gbpserial.c, GemPC410/gbpserial.h: differentiate return values of gbpserial.c regarding GBP errors. * GemPC410/gbpserial.c: use explain_gbp() to log a descriptive GBP level error message * MANIFEST: add README.410 * common/Makefile: use OBJS= to avoid repetitions * README, README.410: README.410 is specific to libGemPC410.so * GemPC410/GemPC410Utils.c: log "OS string" at CRITICAL level to always have it the logs * GemPC410/Makefile: do not compile directly files in common/ but use 'make -C ../common' (avoid '../common/[...]' in log messages) * GemPC430/Makefile: do not compile directly files in common/ but use "make -C ../common" (avoid "../common/[...]" in log messages) * GemPC430/GemPC430Utils.c: log "OS string" at CRITICAL level to always have it the logs * GemPC430/TODO.txt: done: - re-organise sources of ifdhandler.c - modify ifdhandler.c from GemPC430 to GemPC - use a more elegant mechanism for log_function * common/ifdhandler.c: Source file reindentation * common/ifdhandler.c: Add APDU logging * GemPC430/GemPC430Utils.c: Get and print the GemCore version * GemPC410/GemPC410Utils.c: reindent * GemPC430/usblinux.c: Print USB device info in 0x%04X format instead of %d * GemPC430/usblinux.c: Open /proc/bus/usb/00x/00y in read only mode to find the good device. When identified the device is re-opened read/write. * GemPC430/usblinux.c: use DEBUG_CRITICAL3 to be more informative * common/GCdebug.h: added support for DEBUG_CRITICAL3() 2001-11-15 Ludovic Rousseau * README: release 0.5.6 * common/pcscdefines.h: define type status_t * common/ifdhandler.c: add argument &length to GCCmdCardStatus * common/GemCore.h: define type gcore_t * common/GCUtils.h: change return values type from RESPONSECODE to ifd_t * common/GCUtils.c: reindentation change return value types from RESPONSECODE to ifd_t correct return value of functions called * common/GCTransport.h: change return values type from RESPONSECODE to status_t * common/GCCmds.h: change return values type from RESPONSECODE to ifd_t * common/GCCmds.c: migration of GCCmdConfigureSIOLine() to GCMakeCommand() * common/GCCmds.c: change return values type from RESPONSECODE to ifd_t complete migration from GCSendCommand() to GCMakeCommand() * GemPC410/resetGemPC410.c: small typo * GemPC410/main.c: add IFDHTransmitToICC test print return values (SW) * GemPC410/gbpserial.c: removed GCCmdGetOSVersion() and GCCmdSetMode() (moved to GemPC410Utils.c) add explain_gbp() (only used for GBP debug) * GemPC410/TODO.txt: add "create /dev/pcsc/[1-4] at module installation" * GemPC410/Makefile: add -D_REENTRANT compilation flag add strip --strip-unneeded on the library * GemPC410/GemPC410Utils.c: add GCCmdGetOSVersion() call. result not yet checked. * GemPC410/GCGBPTransport.c: change return value type from to status_t * GemPC430/main.c: removed and use ../GemPC410/main.c instead * GemPC430/usbserial_linux.c, GemPC430/usbserial_mosx.c: change return value types from to status_t * GemPC430/usbserial_linux.c, GemPC430/usbserial.h: change return value types from RESPONSECODE to gcore_t * GemPC430/usblinux.c: print the error message instead of the filename when open fail * GemPC430/Makefile: use main.c from ../GemPC410/ to avoid code duplication * GemPC430/GemPC430Utils.h, GemPC430/GemPC430Utils.c: OpenGemPC430() CloseGemPC430(): change return value type from RESPONSECODE to ifd_t * GemPC430/GCUSBTransport.c: change return value type from RESPONSECODE to status_t 2001-11-08 Ludovic Rousseau * common/GCCmds.c, common/GemCore.h: Added GemCore error code "Card Absent" 2001-11-07 Ludovic Rousseau * common/GCCmds.c, common/GCCmds.h, common/GCUtils.h: removed "All rights reserved" which is a nonsense for an Free Software * common/GCUtils.c: iLunCheck(): add a test (LunToReaderIndex(Lun) < 0) * README: release 0.5.5 * GemPC410/GemPC410Utils.c, GemPC410/GemPC410Utils.h: new files * GemPC430/usbserial_linux.c: define USBMAX_READERS as (PCSCLITE_MAX_CHANNELS) instead of 4 * GemPC430/usbserial_mosx.c: use DEBUG_XXD instead of a for (i=0;...) loop in WriteUSB() also * GemPC410/Makefile: added the install rule * MANIFEST: added common/{pcsclite.h, winscard.h, wintypes.h} * GemPC430/Makefile: remove ifd-GemPC430.bundle/Contents/Linux/libGemPC430.so in rule clean * GemPC430/Info.plist: new file * GemPC430/Makefile: renamed ifd-GemPC430 to libGemPC430.so * common/pcsclite.h, common/winscard.h, common/wintypes.h: new files nedded to compile the drivers without installing pcscd before. This solves a chicken and egg problem under Debian * GemPC430/GemPC430Utils.c, GemPC430/Makefile: removed the "," in DEBUG_CRITICAL("OpenUSB failed", ); * GemPC410/Makefile: add GemPC410Utils.o to the list of objects * GemPC410/Config.h: change OpenGBP, CloseGBP to OpenGemPC410, CloseGemPC410 * common/ifdhandler.c: changed ../GemPC410/gbpserial.h to ../GemPC410/GemPC410Utils.h * MANIFEST: added GemPC410/GemPC410Utils.c and GemPC410/GemPC410Utils.h * GemPC430/GemPC430Utils.c: changed CloseREADER_NAME to CloseUSB * GemPC430/GemPC430Utils.c: removed a silly #include "GemPC430Utils.c" * GemPC430/GemPC430Utils.c, GemPC430/GemPC430Utils.h: removed "All rights reserved." which is in contradiction with COPYING * GemPC430/usbserial.h: go back to xxxUSB from xxxGemPC430. This is not the good layer to patch. * GemPC430/GemPC430Utils.c: change OpenREADER_NAME to OpenUSB * GemPC430/Config.h: Changed back to ReadUSB and WriteUSB from a wrong patch to ReadGemPC430 and WriteGemPC430 * README: changed to * common/ifdhandler.c: renamed ../GemPC430/usbserial.h to ../GemPC430/GemPC430Utils.h * common/GCdebug.c: changed LOG_DEBUG to LOG_INFO in syslog() * common/GCUtils.c: add #include "GCTransport.h" 2001-11-06 Ludovic Rousseau * GemPC430/usbserial_mosx.c: use DEBUG_XXD instead of a for (i=0;...) loop * GemPC430/usbserial_mosx.c: Change log_fucntion() to DEBUG_xyz() * GemPC430/usbserial.h: add #ifndef _USBSERIAL_H_ test * GemPC430/GemPC430Utils.h: Added argument channel to OpenGemPC430() * GemPC430/usbserial.h: renamed xxUSB into xxGemPC430 * GemPC430/GemPC430Utils.c: Added argument channel to OpenGemPC430() * GemPC430/Config.h: renamed xxUSB into xxGemPC430 * common/GCCmds.c: removed GCCmdRestart() which is not used anywhere 2001-10-29 Ludovic Rousseau * GemPC430/GemPC430Utils.c: change .c into .h * GemPC430/Makefile, GemPC410/Makefile: define GEMPC in the 'make dep' rule 2001-10-28 Ludovic Rousseau * MANIFEST: renamed COPYING to COPYING.BSD or COPYING.GPL * GemPC430/Makefile: rm -r for ifd-GemPC430.bundle * common/GCUtils.c: Added a comment for iLunCheck() return value * common/GCUtils.c: Changed inegality check in iLunCheck() * README: added history and licences parts * common/GCCmds.c, common/GCCmds.h, common/GCTransport.h, common/GCUtils.c, common/GCUtils.h, common/GCdebug.c, common/GCdebug.h, common/GemCore.h, common/ifdhandler.c, common/ifdhandler.h, common/pcscdefines.h: added reference to the double licence BSD/GPL except for ifdhandler.c and ifdhandler.h which are written by David Corcoran and are under BSD only. * common/COPYING, common/COPYING.BSD, common/COPYING.GPL: renamed COPYING to COPYING.BSD and added COPYING.GPL * GemPC430/GemPC430Utils.c, GemPC430/GemPC430Utils.h, GemPC430/usblinux.c, GemPC430/usblinux.h, GemPC430/usbserial.h, GemPC430/usbserial_linux.c, GemPC430/usbserial_mosx.c: Added licence reference * GemPC410/CmdGemCore.c, GemPC410/CmdGemCore.h: removed CmdGemCore.h CmdGemCore.c (they are in common/ now) * GemPC410/COPYING, GemPC410/COPYING.GPL, GemPC410/GCGBPTransport.h, GemPC410/TODO.txt, GemPC410/resetGemPC410.c: Add GPL text in source files 2001-10-25 Ludovic Rousseau * MANIFEST, GemPC430/Makefile, GemPC430/main.c, GemPC430/GemPC430Utils.c, GemPC430/GemPC430Utils.h, GemPC430/Config.h, GemPC430/Config.h_do_not_use_anymore, GemPC430/GCUSBTransport.h, common/COPYING, common/GCCmds.c, common/GCCmds.h, common/GCTransport.h, common/GCUtils.c, common/GCUtils.h, common/GCdebug.c, common/GCdebug.h, common/debug.c, common/debug.h, GemPC410/Config.h, GemPC410/GCGBPTransport.c, GemPC410/Makefile, GemPC410/gbpserial.c, GemPC410/gbpserial.h, GemPC410/main.c, common/GemCore.h, common/Makefile, common/ifdhandler.c, Makefile, create_distrib.sh, GemPC430/GCUSBTransport.c, GemPC430/README.Linux, GemPC430/usblinux.c, GemPC430/usbserial.h, GemPC430/usbserial_linux.c: *** empty log message *** 2001-10-22 Ludovic Rousseau * GemPC410/COPYING, GemPC410/CmdGemCore.c, GemPC410/CmdGemCore.h, GemPC410/GCGBPTransport.c, GemPC410/GCGBPTransport.h, GemPC410/Makefile, GemPC410/gbpserial.c, GemPC410/gbpserial.h, GemPC410/main.c, GemPC410/resetGemPC410.c, GemPC430/COPYING, GemPC430/Config.h_do_not_use_anymore, GemPC430/English.lproj/InfoPlist.strings, GemPC430/GCUSBTransport.c, GemPC430/GCUSBTransport.h, GemPC430/Makefile, GemPC430/README.Linux, GemPC430/TODO.txt, GemPC430/ifd-GemPC430.pbproj/giraud.pbxuser, GemPC430/ifd-GemPC430.pbproj/project.pbxproj, GemPC430/usblinux.c, GemPC430/usblinux.h, GemPC430/usbserial.h, GemPC430/usbserial_linux.c, GemPC430/usbserial_mosx.c, Makefile, README, common/GemCore.h, common/Makefile, common/debug.c, common/debug.h, common/ifdhandler.c, common/ifdhandler.h, common/pcscdefines.h: Imported sources * GemPC410/COPYING, GemPC410/CmdGemCore.c, GemPC410/CmdGemCore.h, GemPC410/GCGBPTransport.c, GemPC410/GCGBPTransport.h, GemPC410/Makefile, GemPC410/gbpserial.c, GemPC410/gbpserial.h, GemPC410/main.c, GemPC410/resetGemPC410.c, GemPC430/COPYING, GemPC430/Config.h_do_not_use_anymore, GemPC430/English.lproj/InfoPlist.strings, GemPC430/GCUSBTransport.c, GemPC430/GCUSBTransport.h, GemPC430/Makefile, GemPC430/README.Linux, GemPC430/TODO.txt, GemPC430/ifd-GemPC430.pbproj/giraud.pbxuser, GemPC430/ifd-GemPC430.pbproj/project.pbxproj, GemPC430/usblinux.c, GemPC430/usblinux.h, GemPC430/usbserial.h, GemPC430/usbserial_linux.c, GemPC430/usbserial_mosx.c, Makefile, README, common/GemCore.h, common/Makefile, common/debug.c, common/debug.h, common/ifdhandler.c, common/ifdhandler.h, common/pcscdefines.h: New file. ifd-gempc-1.0.7/common/0000755000175000017500000000000011740401711015134 5ustar rousseaurousseauifd-gempc-1.0.7/common/GCUtils.h0000644000175000017500000000223310561621210016615 0ustar rousseaurousseau/* * GCUtils.h * $Id: GCUtils.h,v 1.5 2004-07-03 21:42:48 rousseau Exp $ * ifd-GemPC * * Created by giraud on Sat Oct 20 2001. * Updated by Ludovic Rousseau, Oct 2001 * Copyright (c) 2001 Jean-Luc Giraud & Ludovic Rousseau * * License: this code is under a double licence COPYING.BSD and COPYING.GPL * */ #ifndef _GCUTILS_H_ #define _GCUTILS_H_ #define LunToReaderIndex(Lun) (Lun>>16) /* Check if the Lun is not to large for the pgSlots table */ int iLunCheck(DWORD Lun); ifd_t gemcore_ISO_OUTPUT_processing(DWORD Lun, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength); ifd_t gemcore_ISO_INPUT_processing(DWORD Lun, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength); ifd_t gemcore_ISO_EXCHANGE_processing(DWORD Lun, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength); ifd_t gemcore_status_processing(DWORD nlength, PDWORD RxLength, PUCHAR pcbuffer, PUCHAR RxBuffer); ifd_t gemcore_long_data_OUTPUT_processing(DWORD Lun, UCHAR cCMD, DWORD nbuf_size, PDWORD RxLength, PUCHAR pcbuffer); ifd_t gemcore_long_data_INPUT_processing(DWORD Lun, UCHAR cCMD, DWORD nlength, PUCHAR pcbuffer); #endif ifd-gempc-1.0.7/common/COPYING.GPL0000644000175000017500000004311010445301074016611 0ustar rousseaurousseau GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ifd-gempc-1.0.7/common/.dependencies0000644000175000017500000000000011740401711017551 0ustar rousseaurousseauifd-gempc-1.0.7/common/COPYING.BSD0000644000175000017500000000260610445301074016604 0ustar rousseaurousseauCopyright (c) 2001 Jean-Luc Giraud All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ifd-gempc-1.0.7/common/GCdebug.c0000644000175000017500000000216411740361173016612 0ustar rousseaurousseau/* * $Id: GCdebug.c,v 1.10 2012/04/08 19:09:47 rousseau Exp $ * GCdebug.c: log (or not) messages * Copyright (C) 2001 Ludovic Rousseau * * License: this code is under a double licence COPYING.BSD and COPYING.GPL * */ #include "Config.h" #include "GCdebug.h" #include #include #include #define DEBUG_BUF_SIZE (256*3+30) static char DebugBuffer[DEBUG_BUF_SIZE]; void log_msg(const int priority, const char *fmt, ...) { va_list argptr; (void)priority; va_start(argptr, fmt); vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr); va_end(argptr); fprintf(stderr, "%s\n", DebugBuffer); } /* debug_msg */ void log_xxd(const int priority, const char *msg, const unsigned char *buffer, const int len) { int i; char *c, *debug_buf_end; (void)priority; debug_buf_end = DebugBuffer + DEBUG_BUF_SIZE - 5; strncpy(DebugBuffer, msg, sizeof(DebugBuffer)-1); c = DebugBuffer + strlen(DebugBuffer); for (i = 0; (i < len) && (c < debug_buf_end); ++i) { sprintf(c, "%02X ", buffer[i]); c += strlen(c); } fprintf(stderr, "%s\n", DebugBuffer); } /* debug_xxd */ ifd-gempc-1.0.7/common/gempc_ifdhandler.h0000644000175000017500000000171010561621137020565 0ustar rousseaurousseau/***************************************************************** / / File : gempc_ifdhandler.h / Author : Ludovic Rousseau / Date : 22 october 2001 / Purpose: This provides reader specific low-level calls. / License: See file LICENSE.BSD / / $Id: gempc_ifdhandler.h,v 1.2 2004-07-03 21:02:42 rousseau Exp $ / ******************************************************************/ #ifndef _gempc_ifd_handler_h_ #define _gempc_ifd_handler_h_ #ifdef __cplusplus extern "C" { #endif #include void IFDSetEmv(DWORD lun); /* do not use RESPONSECODE (long, 64 bits) when 32 bits are enough */ typedef int ifd_t; typedef enum { STATUS_SUCCESS = 0xFA, STATUS_UNSUCCESSFUL = 0xFB, STATUS_COMM_ERROR = 0xFC, STATUS_DEVICE_PROTOCOL_ERROR = 0xFD } status_t; #define PCSCLITE_MAX_READERS PCSCLITE_MAX_READERS_CONTEXTS #ifdef __cplusplus } #endif #endif /* _gempc_ifd_hander_h_ */ ifd-gempc-1.0.7/common/GCTransport.h0000644000175000017500000000127410561621210017515 0ustar rousseaurousseau/* * $Id: GCTransport.h,v 1.4 2004-07-03 21:42:48 rousseau Exp $ * GCGBPTransport.h * ifd-GemPC430 * * Created by JL Giraud on Sun Nov 19 2000. * * License: this code is under a double licence COPYING.BSD and COPYING.GPL * */ #ifndef _GCGBPTRANSPORT_H_ #define _GCGBPTRANSPORT_H_ #include "GemCore.h" /* buffer size at transport level (largest of cmd level ones +1) */ #define GC_TR_BUF_SIZE (((CMD_BUF_SIZE #include #include "gempc_ifdhandler.h" #include "Config.h" #include "GemCore.h" #include "GCdebug.h" #include "GCUtils.h" #include "GCCmds.h" #include "GCTransport.h" #if GEMPC==410 #include "../GemPC410/gbpserial.h" #endif #if GEMPC==430 #include "../GemPC430/usbserial.h" #endif #ifndef GEMPC #error "GEMPC not defined: set it to 410 or 430" #endif /* p. 18 Set Mode */ #define IFD_CMD_MODE_SET1 0x01 #define IFD_CMD_MODE_SET2 0x00 /* p. 17 Configure SIO line */ #define IFD_CMD_SIO_SET 0x0A /* p. 21 Restart, p. 22 Restart and Run Specified Application */ #define IFD_CMD_RESTART 0x0C /* p. 24 Set Reader in Halt Mode */ #define IDF_CMD_HALT 0x0E /* p. 26 Power Down */ #define IFD_CMD_ICC_POWER_DOWN 0x11 /* p. 34 Power Up - Asynchronous Cards, p. 36 Change Card Communication * Parameters - Asynchronous Cards, p. 45 Power UP - EMV Compliant, * p. 51 Change Transparent Mode Parameters, p. 53 Power Up - Transparent * Mode, * p. 57 Power Up - Synchronous Cards */ #define IFD_CMD_ICC_POWER_UP 0x12 /* options for IFD_CMD_ICC_POWER_UP command, p. 34 * Class A: Vcc for card is 5V */ #define IFD_CMD_ICC_POWER_UP_OPT_5V 0x01 /* Class B: Vcc for card is 3V */ #define IFD_CMD_ICC_POWER_UP_OPT_3V 0x02 /* Class AB: Vcc for card is 5V or 3V */ #define IFD_CMD_ICC_POWER_UP_OPT_5V_3V (IFD_CMD_ICC_POWER_UP_OPT_5V|IFD_CMD_ICC_POWER_UP_OPT_3V) /* Reset and no PPS management. The reader stays at 9600 baud if the card is * in negotiable mode */ #define IFD_CMD_ICC_POWER_UP_OPT_NO_PPS_MNGT 0x10 /* Reset and no PPS management. Reader switches to maximum speed and T=1 if * card in negotiable mode */ #define IFD_CMD_ICC_POWER_UP_OPT_AUTO_PPS_MNGT 0x20 /* p. 38 ISO Output - Asynchronous Card, * p. 58 Read Data From Synchronous Card (ISO Out) */ #define IFD_CMD_ICC_ISO_OUT 0x13 /* p. 39 ISO Input - Asynchronous Card, * p. 59 Send Data to Synchronous Card (ISO In) */ #define IFD_CMD_ICC_ISO_IN 0x14 /* p. 40 Exchange APDU - Asynchronous Card, * p. 46 Exchange APDU - EMV Compliant, * p. 54 Exchange Block - Transparent Mode, * p. 60 Exchange with Synchronous Card (ADPU) */ #define IFD_CMD_ICC_APDU 0x15 #define IFD_CMD_ICC_SYNCHRONE 0x16 #define IFD_CMD_ICC_DISPATCHER "\x17\x01" /* p. 27 Define Main Card Type and Card Presence Detection */ #define IFD_CMD_ICC_DEFINE_TYPE 0x17 /* p. 43 Card Status - Asynchronous Card, * p. 49 Card Status - EMV Compliant, * p. 55 Card Status - Transparent Mode, * p. 61 Card Status - Synchronous Card */ #define IFD_CMD_ICC_STATUS 0x17 /* p. 31 Directory, * p. 32 Set Operating Mode */ #define IFD_CMD_DIR1 0x17 #define IFD_CMD_DIR2 0x00 #define IFD_EMV_MODE 0x45 #define IFD_GENERIC_MODE 0x47 #define IFD_CMD_MOD_POWER_DOWN 0x19 /* p. 34 Power Up - Asynchronous Cards, * p. 36 Change Card Communication Parameters - Asynchronous Cards, * p. 45 Power UP - EMV Compliant, * p. 51 Change Transparent Mode Parameters, * p. 53 Power Up - Transparent Mode, * p. 57 Power Up - Synchronous Cards */ #define IFD_CMD_MOD_POWER_UP 0x1A /* p. 38 ISO Output - Asynchronous Card, * p. 58 Read Data From Synchronous Card (ISO Out) */ #define IFD_CMD_MOD_ISO_OUT 0x1B /* p. 39 ISO Input - Asynchronous Card, * p. 59 Send Data to Synchronous Card (ISO In) */ #define IFD_CMD_MOD_ISO_IN 0x1C /* p. 40 Exchange APDU - Asynchronous Card, * p. 46 Exchange APDU - EMV Compliant, * p. 54 Exchange Block - Transparent Mode, * p. 60 Exchange with Synchronous Card (ADPU) */ #define IFD_CMD_MOD_APDU 0x1D #define IFD_CMD_MOD_SYNCHRONE 0x1E /* p. Define Type and Select Auxiliary Card */ #define IFD_CMD_MOD_DEFINE_TYPE 0x1F #define IFD_CMD_MOD_DISPATCHER "\x1F\x01" /* p. 43 Card Status - Asynchronous Card, * p. 49 Card Status - EMV Compliant, * p. 55 Card Status - Transparent Mode, * p. 61 Card Status - Synchronous Card */ #define IFD_CMD_MOD_STATUS 0x1F /* p. 20 Read Firmware Version, * p. 63 Read Memory */ #define IFD_CMD_MEM_RD 0x22 /* p. 19 Set Delay, * p. 64 Write Memory */ #define IFD_CMD_MEM_WR 0x23 /* p. 69 Read CPU Port */ #define IFD_CMD_CPU_RD 0x24 /* p. 70 Write CPU Port */ #define IFD_CMD_CPU_WR 0x25 /* p. 66 Erase Flash Memory */ #define IFD_CMD_MEM_ERASE 0x26 /* p. 68 Select External Memory Page */ #define IFD_CMD_MEM_SELECT 0x27 #define IFD_CMD_LCD_OFF 0x29 /* p. 72 Init the LCD */ #define IFD_CMD_LCD_ON 0x2A /* p. 73 Display Character String */ #define IFD_CMD_LCD_STRING 0x2B /* p. 74 Display Character */ #define IFD_CMD_LCD_CHAR 0x2C /* p. 75 Send LCD Command */ #define IFD_CMD_LCD_CMD 0x2D /* p. 77 Set Key Press Timeout */ #define IFD_CMD_KEY_TIMEOUT 0x32 /* p. 78 Sound Buzzer */ #define IFD_CMD_SOUND_BUZZER 0x33 /* p. 80 Read Date and Time */ #define IFD_CMD_RTC_RD 0x3A /* p. 81 Update Date and Time */ #define IFD_CMD_RTC_WR 0x3B #define IFD_CMD_IO_RD 0x42 #define IFD_CMD_IO_WR 0x43 #define IFD_CMD_IO_BIT_WR 0x44 #define IFD_TYP_VERSION 0x05 #define IFD_ADD_VERSION_HIGH 0x3F #define IFD_ADD_VERSION_LOW 0xE0 ifd_t GCCmdPowerDown(const DWORD lun) { UCHAR cmd[] = { IFD_CMD_ICC_POWER_DOWN }; ifd_t rv; gcore_t gc_rv; DEBUG_INFO(""); /* PowerDown the card */ rv = GCMakeCommand(lun, sizeof(cmd), cmd, NULL, NULL, &gc_rv); GCGemCoreError(gc_rv, __FILE__, __LINE__, __FUNCTION__); if (rv != IFD_SUCCESS) return rv; if (gc_rv != GCORE_OK) /* There is a problem in power down */ return IFD_ERROR_POWER_ACTION; return IFD_SUCCESS; } /* GCCmdPowerDown */ ifd_t GCCmdPowerUp(const DWORD lun, PDWORD nlength, UCHAR buffer[]) { #ifdef AUTOMATIC_PPS UCHAR cmd_auto_pps[] = { IFD_CMD_ICC_POWER_UP, IFD_CMD_ICC_POWER_UP_OPT_5V_3V | IFD_CMD_ICC_POWER_UP_OPT_AUTO_PPS_MNGT }; #endif UCHAR cmd_no_pps[] = { IFD_CMD_ICC_POWER_UP, IFD_CMD_ICC_POWER_UP_OPT_5V_3V | IFD_CMD_ICC_POWER_UP_OPT_NO_PPS_MNGT }; UCHAR cmd_emv[] = { IFD_CMD_ICC_POWER_UP }; UCHAR cmd_set_operating_mode[] = { IFD_CMD_DIR1, IFD_CMD_DIR2, IFD_GENERIC_MODE }; ifd_t rv; gcore_t gc_rv; DEBUG_INFO(""); #ifdef AUTOMATIC_PPS /* PowerUp the card with automatic PPS negociation */ rv = GCMakeCommand(lun, sizeof(cmd_auto_pps), cmd_auto_pps, nlength, buffer, &gc_rv); GCGemCoreError(gc_rv, __FILE__, __LINE__, __FUNCTION__); if (rv != IFD_SUCCESS) return rv; /* There is a problem in power up: try with NO PPS */ if ((gc_rv != GCORE_OK) && (gc_rv != GCORE_WRONG_TCK)) #endif { rv = GCMakeCommand(lun, sizeof(cmd_no_pps), cmd_no_pps, nlength, buffer, &gc_rv); GCGemCoreError(gc_rv, __FILE__, __LINE__, __FUNCTION__); if (rv != IFD_SUCCESS) return rv; /* There is a problem in power up: try to use EMV mode */ if ((gc_rv != GCORE_OK) && (gc_rv != GCORE_WRONG_TCK)) { /* power up: will return a 0xA0 error or EMV ok */ rv = GCMakeCommand(lun, sizeof(cmd_emv), cmd_emv, nlength, buffer, &gc_rv); GCGemCoreError(gc_rv, __FILE__, __LINE__, __FUNCTION__); /* If the card is NOT EMV we continue */ if (gc_rv != GCORE_OK) { /* set mode to ISO */ rv = GCMakeCommand(lun, sizeof(cmd_set_operating_mode), cmd_set_operating_mode, nlength, buffer, &gc_rv); GCGemCoreError(gc_rv, __FILE__, __LINE__, __FUNCTION__); /* new power up */ rv = GCMakeCommand(lun, sizeof(cmd_no_pps), cmd_no_pps, nlength, buffer, &gc_rv); GCGemCoreError(gc_rv, __FILE__, __LINE__, __FUNCTION__); } else /* the card is EMV */ IFDSetEmv(lun); if (rv != IFD_SUCCESS) return rv; } /* There is a problem in power up */ if ((gc_rv != GCORE_OK) && (gc_rv != GCORE_WRONG_TCK)) return IFD_ERROR_POWER_ACTION; } return IFD_SUCCESS; } /* GCCmdPowerUp */ ifd_t GCCmdGetOSVersion(const DWORD lun, PDWORD length, UCHAR buffer[]) { /* * GCR 400 (OROS): 'OROS-R2.24RM ' (without ') * (GemCore): incorrect number of arguments (error 03) * * GCR 410 (OROS): OROS-R2.99-R1.10 * v1.10 (GemCore): GemCore-R1.10-0M * * GCR 410P (OROS): OROS-R2.99-R1.11 * v1.118 (GemCore): 'GemCore-R1.11-8 ' (without ') * * GemPC 410 (OROS): OROS-R2.99-R1.21 * v1.21 (GemCore): GemCore-R1.21-GM * * GemPC 413 (OROS): OROS-R2.99-R1.32 * v1.32 (GemCore): GemCore-R1.32-GK */ UCHAR cmd[] = { IFD_CMD_MEM_RD, IFD_TYP_VERSION, IFD_ADD_VERSION_HIGH, IFD_ADD_VERSION_LOW, IFD_LEN_VERSION }; gcore_t gc_rv; DEBUG_INFO(""); if (*length < IFD_LEN_VERSION) { DEBUG_CRITICAL("buffer too small"); return IFD_COMMUNICATION_ERROR; } /* clear the buffer to be sure it is \0 terminated */ memset(buffer, 0, *length); /* decrease length by 1 to be sure their is room for the final \0 */ (*length)--; GCMakeCommand(lun, sizeof(cmd), cmd, length, buffer, &gc_rv); GCGemCoreError(gc_rv, __FILE__, __LINE__, __FUNCTION__); if (gc_rv != GCORE_OK) return IFD_ERROR_POWER_ACTION; return IFD_SUCCESS; } /* GCCmdGetOSVersion */ ifd_t GCCmdConfigureSIOLine(const DWORD lun, const int baudrate) { UCHAR cmd[] = { IFD_CMD_SIO_SET, 0x00 }; ifd_t rv; gcore_t gc_rv; DEBUG_INFO(""); switch (baudrate) { case 9600: cmd[1] = 0x04; break; case 38400: cmd[1] = 0x02; break; default: DEBUG_CRITICAL2("wrong baudrate %d", baudrate); return IFD_COMMUNICATION_ERROR; } rv = GCMakeCommand(lun, sizeof(cmd), cmd, NULL, NULL, &gc_rv); GCGemCoreError(gc_rv, __FILE__, __LINE__, __FUNCTION__); if (rv != IFD_SUCCESS || gc_rv != GCORE_OK) return IFD_COMMUNICATION_ERROR; return rv; } /* GCCmdConfigureSIOLine */ ifd_t GCCmdCardStatus(const DWORD lun, UCHAR response[], PDWORD length) { UCHAR cmd[] = { IFD_CMD_ICC_STATUS }; ifd_t rv; gcore_t gc_rv; DEBUG_PERIODIC(""); rv = GCMakeCommand(lun, sizeof(cmd), cmd, length, response, &gc_rv); GCGemCoreError(gc_rv, __FILE__, __LINE__, __FUNCTION__); if (rv != IFD_SUCCESS || gc_rv != GCORE_OK) return IFD_COMMUNICATION_ERROR; return rv; } /* GCCmdCardStatus */ ifd_t GCCmdSetMode(const DWORD lun, const int mode) { UCHAR cmd[] = { IFD_CMD_MODE_SET1, IFD_CMD_MODE_SET2, mode}; ifd_t rv; gcore_t gc_rv; DEBUG_INFO(""); /* success by default */ rv = IFD_SUCCESS; switch (mode) { case IFD_MODE_ROSNOTLP: rv = GCMakeCommand(lun, sizeof(cmd), cmd, NULL, NULL, &gc_rv); GCGemCoreError(gc_rv, __FILE__, __LINE__, __FUNCTION__); /* The command in unknown if ROS is disabled */ if ((gc_rv != GCORE_UNKNOWN_CMD) && (gc_rv != GCORE_OK)) rv = IFD_COMMUNICATION_ERROR; break; default: DEBUG_CRITICAL2("Unknown mode: %02X", mode); break; } return rv; } /* GCCmdSetMode */ ifd_t GCMakeCommand(const DWORD lun, const DWORD nLengthIn, const UCHAR pcBufferCmd[], PDWORD pnLengthOut, UCHAR pcBufferOut[], gcore_t *response) { UCHAR rv; DWORD lengthout; UCHAR buffer[GC_TR_BUF_SIZE]; /* no error by default */ *response = GCORE_OK; lengthout = sizeof(buffer); rv = GCSendCommand(lun, nLengthIn, pcBufferCmd, &lengthout, buffer); /* transport level error */ if (rv != STATUS_SUCCESS) return IFD_COMMUNICATION_ERROR; /* the reader response was empty */ if (0 == lengthout) return IFD_COMMUNICATION_ERROR; /* GemCore level error */ *response = buffer[GC_STATUS_OFFSET]; /* shift command anwser (remove GemCore status byte) */ if (pcBufferOut) memcpy(pcBufferOut, buffer+1, lengthout-1); /* status byte removed */ if (pnLengthOut) *pnLengthOut = lengthout-1; return IFD_SUCCESS; } /* GCMakeCommand */ UCHAR GCGemCoreError(const UCHAR rv, const char *file, const int line, const char *function) { const char *text = NULL; char log_level = PCSC_LOG_ERROR; /* what is the GemCore status? */ switch (rv) { /* normal error code */ case GCORE_OK: break; case GCORE_UNKNOWN_CMD: text = "Unknown GemCore command"; break; case GCORE_IMPOS_OPERATION: text = "Operation impossible with this driver"; break; case GCORE_INC_NUMBER_ARG: text = "Incorrect number of arguments"; break; case GCORE_RESET_ERROR: text = "The first byte of the response (TS) is not valid"; break; case GCORE_POWERED_DOWN: text = "Card powered down. Power up first"; break; case GCORE_MORE_DATA: text = "Incorrect number of parameters"; break; case GCORE_WRONG_TCK: text = "Wrong ATR TCK"; break; case GCORE_ATR: text = "Error in card reset response"; break; case GCORE_CARD_PROT_ERR: text = "Card protocol error"; break; case GCORE_CARD_MUTE: text = "Card is mute"; break; case GCORE_PARITY_ERROR: text = "Parity error during exchange"; break; case GCORE_CARD_T1_ABORT: text = "Card has aborted chaining (T=1)"; break; case GCORE_READER_T1_ABORT: text = "Reader has aborted chaining (T=1)"; break; case GCORE_RESYNC: text = "RESYNCH successfully performed by GemCore"; break; case GCORE_PTS: text = "Protocol Type Selection (PTS) error"; break; case GCORE_CARD_YON: text = "Card and reader in EMV mode"; break; case GCORE_INVALID_PROC_BYTE: text = "The card just sent an invalid Procedure Byte"; break; /* normal error code */ case GCORE_CARD_EXC_INT: text = "Card interrupted the exchange after SW1"; log_level = PCSC_LOG_INFO; break; /* normal error code */ case GCORE_NOT_9000: text = "\"Error\" returned by the card (SW is not 9000)"; log_level = PCSC_LOG_INFO; break; case GCORE_CARD_REMOVED: text = "Card removed during execution of a command"; break; case GCORE_CARD_MISSING: text = "Card missing"; break; default: log_msg(PCSC_LOG_ERROR, "%s:%d %s Unknown or undocumented error: 0x%02X", file, line, function, rv); break; } if (text) log_msg(log_level, "%s:%d %s %s", file, line, function, text); return rv; } /* GCGemCoreError */ ifd-gempc-1.0.7/common/GCUtils.c0000644000175000017500000002755711740361173016641 0ustar rousseaurousseau/* * $Id: GCUtils.c,v 1.23 2012/04/08 19:09:47 rousseau Exp $ * GCUtils.c * ifd-GemPC * * Created by giraud on Sat Oct 20 2001. * Updated by Ludovic Rousseau, Oct-Nov 2001 * Copyright (c) 2001 Jean-Luc Giraud & Ludovic Rousseau * * License: this code is under a double licence COPYING.BSD and COPYING.GPL * */ #include #include #include "gempc_ifdhandler.h" #include "Config.h" #include "GCUtils.h" #include "GCTransport.h" #include "GemCore.h" #include "GCdebug.h" #include "GCCmds.h" /* p. 38 ISO Output - Asynchronous Card, * p. 58 Read Data From Synchronous Card (ISO Out) */ #define IFD_CMD_ICC_ISO_OUT 0x13 /* p. 39 ISO Input - Asynchronous Card, * p. 59 Send Data to Synchronous Card (ISO In) */ #define IFD_CMD_ICC_ISO_IN 0x14 /* p. 40 Exchange APDU - Asynchronous Card, * p. 46 Exchange APDU - EMV Compliant, * p. 54 Exchange Block - Transparent Mode, * p. 60 Exchange with Synchronous Card (ADPU) */ #define IFD_CMD_ICC_APDU 0x15 const UCHAR pcLongDataADPU[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* Check if the Lun is not to large for the pgSlots table * returns TRUE in case of error */ int iLunCheck(DWORD Lun) { if (LunToReaderIndex(Lun) >= PCSCLITE_MAX_READERS) return TRUE; return FALSE; } /* iLunCheck */ ifd_t gemcore_ISO_OUTPUT_processing(DWORD Lun, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength) { UCHAR pccmd_buffer[CMD_BUF_SIZE]; UCHAR pcbuffer[RESP_BUF_SIZE]; DWORD nlength, ntemp_length; ifd_t return_value = IFD_SUCCESS; /* Assume it will work */ DEBUG_INFO(""); /* Buffer only holds an APDU (no Data), * output command */ pccmd_buffer[GC_OFFSET_CMD] = IFD_CMD_ICC_ISO_OUT; memcpy(pccmd_buffer + GC_OFFSET_APDU, TxBuffer, TxLength); /* Send the command */ nlength = sizeof(pcbuffer); if (GCSendCommand(Lun, TxLength + GC_SIZE_CMD, pccmd_buffer, &nlength, pcbuffer) != STATUS_SUCCESS) { DEBUG_CRITICAL("ISO Output failed"); return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } /* Copy RxLength to memorize the RxBuffer size */ ntemp_length = *RxLength; return_value = gemcore_status_processing(nlength, RxLength, pcbuffer, RxBuffer); /* Check if command was successful */ if (return_value != IFD_SUCCESS) goto clean_up_and_return; /* Check if there is more data to fetch * First check for 0 length */ if (TxBuffer[ISO_OFFSET_LENGTH] == 0) { /* APDU Lenght byte is 0, check if card sent Data (256 Data) */ if (nlength <= (ISO_SIZE_SW + GC_READER_TRANSMIT_RESP_LENGTH)) /* Length was 0 and card returned no data: Case 1 command */ goto clean_up_and_return; /* Data are left * set nlength to remaining space avaliable in RxBuffer */ nlength = ntemp_length - *RxLength; if (nlength <= 0) { return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } /* Retrieve remaining data and paste it after the first half */ return_value = gemcore_long_data_OUTPUT_processing(Lun, IFD_CMD_ICC_ISO_OUT, nlength, RxLength, RxBuffer + *RxLength); } else if ((TxBuffer[ISO_OFFSET_LENGTH] > GC_ISO_OUTPUT_MAX_DATA_LENGTH) && (nlength-ISO_SIZE_SW >= GC_ISO_OUTPUT_MAX_DATA_LENGTH)) { /* Data are left * set nlength to remaining space avaliable in pcbuffer */ nlength = ntemp_length - *RxLength; /* Retrieve remaining data and paste it after the first half */ return_value = gemcore_long_data_OUTPUT_processing(Lun, IFD_CMD_ICC_ISO_OUT, nlength, RxLength, RxBuffer + *RxLength); } clean_up_and_return: /* Buffers clean-up */ bzero(pccmd_buffer, sizeof(pccmd_buffer)); bzero(pcbuffer, sizeof(pcbuffer)); if (return_value != IFD_SUCCESS) *RxLength = 0; return return_value; } /* gemcore_ISO_OUTPUT_processing */ ifd_t gemcore_ISO_INPUT_processing(DWORD Lun, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength) { UCHAR pccmd_buffer[CMD_BUF_SIZE]; UCHAR pcbuffer[RESP_BUF_SIZE]; DWORD nlength; ifd_t return_value = IFD_SUCCESS; /* Assume it will work */ DEBUG_INFO(""); nlength = TxBuffer[ISO_OFFSET_LENGTH]; #if 0 /* * this part of code is disabled since a nlength == 0 si used for Case1 * APDUs (CLA INS P1 P2). They are tranfsormed in ifdhandler.c in * ISO_INPUT (CLA INS P1 P2 00) TPDUs */ if (!nlength) { /* Data field present but Lc=0, forbidden */ return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } #endif if (TxLength < (nlength + ISO_CMD_SIZE + ISO_LENGTH_SIZE)) { /* Not enough Data in TxBuffer */ return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } /* If length exceeds maximum for one exchange, send the last part first */ if (nlength > GC_ISO_INPUT_MAX_DATA_LENGTH) { return_value = gemcore_long_data_INPUT_processing(Lun, IFD_CMD_ICC_ISO_IN, nlength - GC_ISO_INPUT_MAX_DATA_LENGTH, TxBuffer + ISO_CMD_SIZE + ISO_LENGTH_SIZE + GC_ISO_INPUT_MAX_DATA_LENGTH); if (return_value != IFD_SUCCESS) goto clean_up_and_return; /* Length to send is now smaller */ TxLength -= nlength - GC_ISO_INPUT_MAX_DATA_LENGTH; } nlength = sizeof(pcbuffer); pccmd_buffer[GC_OFFSET_CMD] = IFD_CMD_ICC_ISO_IN; memcpy(pccmd_buffer + GC_OFFSET_APDU, TxBuffer, TxLength); if (GCSendCommand(Lun, TxLength + GC_SIZE_CMD, pccmd_buffer, &nlength, pcbuffer) != STATUS_SUCCESS) { DEBUG_CRITICAL("ISO Input failed"); return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } return_value = gemcore_status_processing(nlength, RxLength, pcbuffer, RxBuffer); clean_up_and_return: /* Buffers clean-up */ bzero(pccmd_buffer, sizeof(pccmd_buffer)); bzero(pcbuffer, sizeof(pcbuffer)); if (return_value != IFD_SUCCESS) *RxLength = 0; return return_value; } /* gemcore_ISO_INPUT_processing */ ifd_t gemcore_ISO_EXCHANGE_processing(DWORD Lun, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength) { UCHAR pccmd_buffer[CMD_BUF_SIZE]; UCHAR pcbuffer[RESP_BUF_SIZE]; DWORD nlength; ifd_t return_value = IFD_SUCCESS; /* Assume it will work */ DEBUG_INFO(""); /* If length exceeds maximum for one exchange, send the last part first */ if (TxLength > GC_ISO_EXC_CMD_MAX_APDU_LENGTH) { return_value = gemcore_long_data_INPUT_processing(Lun, IFD_CMD_ICC_APDU, TxLength - GC_ISO_EXC_CMD_MAX_APDU_LENGTH, TxBuffer + GC_ISO_EXC_CMD_MAX_APDU_LENGTH); if (return_value != IFD_SUCCESS) goto clean_up_and_return; /* Length to send is now smaller */ TxLength = GC_ISO_EXC_CMD_MAX_APDU_LENGTH; } /* Build the commmand */ pccmd_buffer[GC_OFFSET_CMD] = IFD_CMD_ICC_APDU; memcpy(pccmd_buffer + GC_OFFSET_APDU, TxBuffer, TxLength); /* Add length of expected data */ pccmd_buffer[GC_OFFSET_APDU + TxLength] = *RxLength; /* Send the command */ nlength = sizeof(pcbuffer); if (GCSendCommand(Lun, TxLength + GC_SIZE_CMD, pccmd_buffer, &nlength, pcbuffer) != STATUS_SUCCESS) { DEBUG_CRITICAL("ISO Exchange failed"); return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } if (nlength < GC_SIZE_STATUS) { /* Length should at least be GC_SIZE_STATUS (reader status) */ return IFD_COMMUNICATION_ERROR; } if (pcbuffer[GC_STATUS_OFFSET] == GCORE_MORE_DATA) { if (nlength != (GC_ISO_EXC_RESP_MAX_APDU_LENGTH + GC_SIZE_STATUS)) { /* Should have received a full block */ return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } /* There are extra data to fetch on the reader * store what was receive */ if (*RxLength <= (GC_ISO_EXC_RESP_MAX_APDU_LENGTH)) { memcpy(RxBuffer, pcbuffer + GC_OFFSET_RESP_DATA, *RxLength); /* No space left in buffer, return directly */ goto clean_up_and_return; } memcpy(RxBuffer, pcbuffer + GC_OFFSET_RESP_DATA, GC_ISO_EXC_RESP_MAX_APDU_LENGTH); /* set nlength to remaining space avaliable in RxBuffer */ nlength = *RxLength - GC_ISO_EXC_RESP_MAX_APDU_LENGTH; /* set RxLength to what was already received */ *RxLength = GC_ISO_EXC_RESP_MAX_APDU_LENGTH; /* Retrieve remaining data and paste it after the first half */ return_value = gemcore_long_data_OUTPUT_processing(Lun, IFD_CMD_ICC_APDU, nlength, RxLength, RxBuffer + *RxLength); } else return_value = gemcore_status_processing(nlength, RxLength, pcbuffer, RxBuffer); clean_up_and_return: /* Buffers clean-up */ bzero(pccmd_buffer, sizeof(pccmd_buffer)); bzero(pcbuffer, sizeof(pcbuffer)); if (return_value != IFD_SUCCESS) *RxLength = 0; return return_value; } /* gemcore_ISO_EXCHANGE_processing */ ifd_t gemcore_status_processing(DWORD nlength, PDWORD RxLength, PUCHAR pcbuffer, PUCHAR RxBuffer) { DEBUG_INFO(""); if (nlength < GC_SIZE_STATUS) /* Length should at least be GC_SIZE_STATUS (reader status) */ return IFD_COMMUNICATION_ERROR; nlength -= GC_SIZE_STATUS; switch (GCGemCoreError(pcbuffer[GC_STATUS_OFFSET], __FILE__, __LINE__, __FUNCTION__)) { case GCORE_OK: case GCORE_NOT_9000: case GCORE_CARD_EXC_INT: /* SW=6700 */ /* if ( nlength < pcbuffer[OFFSET_LNG] ) */ /* WHAT SHOULD WE DO */ *RxLength = (*RxLength < nlength) ? (*RxLength) : nlength; memcpy(RxBuffer, pcbuffer + GC_OFFSET_RESP_DATA, *RxLength); break; case GCORE_CARD_MUTE: return IFD_RESPONSE_TIMEOUT; case GCORE_CARD_PROT_ERR: return IFD_PROTOCOL_NOT_SUPPORTED; case GCORE_CARD_MISSING: return IFD_ICC_NOT_PRESENT; default: /* There was a problem in sending the command */ return IFD_COMMUNICATION_ERROR; } return IFD_SUCCESS; } /* gemcore_status_processing */ ifd_t gemcore_long_data_INPUT_processing(DWORD Lun, UCHAR cCMD, DWORD ndatalength, PUCHAR pcbuffer) { UCHAR pccmd_buffer[CMD_BUF_SIZE]; UCHAR pcresp_buffer[RESP_BUF_SIZE]; UCHAR pcresp_buffer2[RESP_BUF_SIZE]; DWORD nlength, nlength2; ifd_t return_value; DEBUG_INFO(""); /* command */ pccmd_buffer[GC_OFFSET_CMD] = cCMD; /* use specific APDU */ memcpy(pccmd_buffer + GC_OFFSET_APDU, pcLongDataADPU, sizeof(pcLongDataADPU)); /* modify the length byte */ pccmd_buffer[GC_OFFSET_LENGTH] = (UCHAR) ndatalength; /* Check the space left in pccmd_buffer */ if (sizeof(pccmd_buffer) < (GC_OFFSET_TPDU_CMD_DATA + ndatalength)) { return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } /* Add the Data (last data bytes of the command */ memcpy(pccmd_buffer + GC_OFFSET_TPDU_CMD_DATA, pcbuffer, ndatalength); /* Send the command */ nlength = sizeof(pcresp_buffer); if (GCSendCommand(Lun, sizeof(pcLongDataADPU) + GC_SIZE_CMD + ndatalength, pccmd_buffer, &nlength, pcresp_buffer) != STATUS_SUCCESS) { DEBUG_CRITICAL("ISO Input failed"); return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } nlength2 = sizeof(pcresp_buffer2); return_value = gemcore_status_processing(nlength, &nlength2, pcresp_buffer, pcresp_buffer2); clean_up_and_return: bzero(pccmd_buffer, sizeof(pccmd_buffer)); bzero(pcresp_buffer, sizeof(pcresp_buffer)); bzero(pcresp_buffer2, sizeof(pcresp_buffer2)); return return_value; } /* gemcore_long_data_INPUT_processing */ /* * nbuf_size should hold the max length available in pcbuffer */ ifd_t gemcore_long_data_OUTPUT_processing(DWORD Lun, UCHAR cCMD, DWORD nbuf_size, PDWORD RxLength, PUCHAR pcbuffer) { UCHAR pccmd_buffer[CMD_BUF_SIZE]; UCHAR pcresp_buffer[RESP_BUF_SIZE]; DWORD nlength; ifd_t return_value; DEBUG_INFO(""); /* command */ pccmd_buffer[GC_OFFSET_CMD] = cCMD; /* use specific APDU */ memcpy(pccmd_buffer + GC_OFFSET_APDU, pcLongDataADPU, sizeof(pcLongDataADPU)); /* Send the command */ nlength = sizeof(pcresp_buffer); if (GCSendCommand(Lun, sizeof(pcLongDataADPU) + GC_SIZE_CMD, pccmd_buffer, &nlength, pcresp_buffer) != STATUS_SUCCESS) { DEBUG_CRITICAL("ISO Output failed"); bzero(pccmd_buffer, sizeof(pccmd_buffer)); bzero(pcresp_buffer, sizeof(pcresp_buffer)); return IFD_COMMUNICATION_ERROR; } return_value = gemcore_status_processing(nlength, &nbuf_size, pcresp_buffer, pcbuffer); *RxLength = *RxLength + nbuf_size; bzero(pccmd_buffer, sizeof(pccmd_buffer)); bzero(pcresp_buffer, sizeof(pcresp_buffer)); return return_value; } /* gemcore_long_data_OUTPUT_processing */ ifd-gempc-1.0.7/common/GemCore.h0000644000175000017500000001025611740361173016641 0ustar rousseaurousseau/* * GemCore.h * $Id: GemCore.h,v 1.17 2012/04/08 19:09:47 rousseau Exp $ * ifd-GemPC * * Created by JL Giraud on Sun Nov 19 2000. * Updated by Ludovic Rousseau , Oct 2001 * * License: this code is under a double licence COPYING.BSD and COPYING.GPL * */ #ifndef _GEMCORE_H_ #define _GEMCORE_H_ #include #ifdef __APPLE__ #include #endif /* Size of an ISO command (CLA+INS+P1+P2) */ #define ISO_CMD_SIZE 4 /* Offset of the length byte in an TPDU */ #define ISO_OFFSET_LENGTH 4 /* Offset of the data in a TPDU */ #define ISO_OFFSET_TPDU_DATA 5 /* ISO length size (1 in general) */ #define ISO_LENGTH_SIZE 1 /* ISO SW size */ #define ISO_SIZE_SW 2 /* Communication buffer size (max=cmd+adpu+Lc+data+Le) */ #define CMD_BUF_SIZE (1+4+1+256+1) /* Larger communication buffer size (max=reader status+data+sw) */ #define RESP_BUF_SIZE (1+256+2) /* Size of the command field in a gemcore command */ #define GC_SIZE_CMD 1 /* Size of the reader status */ #define GC_SIZE_STATUS 1 /* *** should disapear */ /* Offset of the status byte in a reader answer (CMD level) */ #define GC_STATUS_OFFSET 0 /* Offset of the command byte in a GemCore command (CMD level) */ #define GC_OFFSET_CMD 0 /* Offset of the APDU in a GemCore command (CMD level) */ #define GC_OFFSET_APDU 1 /* Offset of the Lc byte in the APDU of a Gemcore command */ #define GC_OFFSET_LENGTH (GC_OFFSET_APDU+ISO_OFFSET_LENGTH) /* Offset of the Data in a TPDU Gemcore command */ #define GC_OFFSET_TPDU_CMD_DATA (GC_OFFSET_APDU+ISO_OFFSET_TPDU_DATA) /* Offset of the DATA in a GemCore response (CMD level) */ #define GC_OFFSET_RESP_DATA 1 /* Nb of bytes added to the APDU in a GemCore command (CMD level) */ #define GC_FORMAT_SIZE 1 /* STAT byte offset in a response to CARD STATUS command (CMD level) */ #define GC_OFFSET_STAT_BYTE 0 /* Bit mask to get the reader power status */ #define GC_MASK_POWER 0x02 /* Bit mask to detect ICC presence */ #define GC_MASK_ICC_PRESENCE 0x04 /* size if CARD STATUS response */ #define GC_SIZE_CARD_STATUS 6 /* Maximum size of Data for ISO_Output before pcLongDataADPU is required */ #define GC_ISO_OUTPUT_MAX_DATA_LENGTH 252 /* Maximum size of Data for ISO_Output before pcLongDataADPU is required */ #define GC_ISO_INPUT_MAX_DATA_LENGTH 248 /* Maximum length for APDU command (ie CMD+2xlength+DataIn) */ #define GC_ISO_EXC_CMD_MAX_APDU_LENGTH 254 /* Maximum length for APDU response (ie Data + SW) */ #define GC_ISO_EXC_RESP_MAX_APDU_LENGTH 254 /* Length of the reader response to a transmit command */ #define GC_READER_TRANSMIT_RESP_LENGTH 1 /* Powerflag (used to detect quick insertion removals unnoticed by the * resource manager) */ /* Initial value */ #define POWERFLAGS_RAZ 0x00 /* Flag set when a power up has been requested */ #define MASK_POWERFLAGS_PUP 0x01 /* Flag set when a power down is requested */ #define MASK_POWERFLAGS_PDWN 0x02 /* Flag set when reader and card are EMV (use only APDU exchange) */ #define MASK_POWERFLAGS_EMV 0x04 /* Size of the GemCore version string */ #define IFD_LEN_VERSION 0x10 /* mode GemCore + ROS - TLP */ #define IFD_MODE_ROSNOTLP 1 /* Gemcore error codes */ typedef enum { GCORE_OK = 0x00, GCORE_UNKNOWN_CMD = 0x01, GCORE_IMPOS_OPERATION = 0x02, GCORE_INC_NUMBER_ARG = 0x03, GCORE_RESET_ERROR = 0x10, GCORE_POWERED_DOWN = 0x15, GCORE_MORE_DATA = 0x1B, GCORE_WRONG_TCK = 0x1D, GCORE_ATR = 0xA0, GCORE_CARD_PROT_ERR = 0xA1, GCORE_CARD_MUTE = 0xA2, GCORE_PARITY_ERROR = 0xA3, GCORE_CARD_T1_ABORT = 0xA4, GCORE_READER_T1_ABORT = 0xA5, GCORE_RESYNC = 0xA6, GCORE_PTS = 0xA7, GCORE_CARD_YON = 0xA8, GCORE_INVALID_PROC_BYTE = 0xE4, GCORE_CARD_EXC_INT = 0xE5, GCORE_NOT_9000 = 0xE7, GCORE_CARD_REMOVED = 0xF7, GCORE_CARD_MISSING = 0xFB } gcore_t; /* Protocols */ enum { T_0 = 0, T_1 = 1 }; typedef struct GCORE_DESC { DWORD nATRLength; UCHAR pcATRBuffer[MAX_ATR_SIZE]; UCHAR bPowerFlags; } GCoreDesc; #ifndef TRUE #define FALSE 0 #define TRUE 1 #endif #endif ifd-gempc-1.0.7/common/ifdhandler.c0000644000175000017500000004524111740361173017415 0ustar rousseaurousseau/***************************************************************** / / File : ifdhandler.c / Authors : David Corcoran / Jean-Luc Giraud / Ludovic Rousseau / Date : April 9, 2001, 2002, 2003, 2004 / Purpose: This provides reader specific low-level calls / for the GemPC family of Gemplus. The function / stubs were written by D. Corcoran, the GemCore / +specific code was added by JL Giraud. / This module implements the command level of GemCore / See http://www.linuxnet.com for more information. / License: See file COPYING.BSD / / $Id: ifdhandler.c,v 1.31 2012/04/08 19:09:47 rousseau Exp $ / ******************************************************************/ #include #include #ifdef HAVE_PTHREAD_H #include #endif #include "gempc_ifdhandler.h" #include "Config.h" #include "GemCore.h" #include "GCUtils.h" #include "GCCmds.h" #include "GCdebug.h" #if GEMPC==410 #include "../GemPC410/GemPC410Utils.h" #endif #if GEMPC==430 #include "../GemPC430/GemPC430Utils.h" #endif #ifndef __CONFIG_H__ #error "GEMPC must be configured (set to 410 or 430)" #endif /* Array of structures to hold the ATR and other state value of each slot */ static GCoreDesc pgSlots[PCSCLITE_MAX_READERS]; RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPSTR lpcDevice) { DEBUG_INFO3("lun: %lX, device: %s", Lun, lpcDevice); if (iLunCheck(Lun)) return IFD_COMMUNICATION_ERROR; /* Reset ATR buffer */ pgSlots[LunToReaderIndex(Lun)].nATRLength = 0; *pgSlots[LunToReaderIndex(Lun)].pcATRBuffer = '\0'; /* Reset PowerFlags */ pgSlots[LunToReaderIndex(Lun)].bPowerFlags = POWERFLAGS_RAZ; if (OpenPortByName(Lun, lpcDevice) != IFD_SUCCESS) { DEBUG_CRITICAL("OpenPort failed"); return IFD_COMMUNICATION_ERROR; } return IFD_SUCCESS; } /* IFDHCreateChannelByName */ RESPONSECODE IFDHCreateChannel(DWORD Lun, DWORD Channel) { /* * Lun - Logical Unit Number, use this for multiple card slots or * multiple readers. 0xXXXXYYYY - XXXX multiple readers, YYYY multiple * slots. The resource manager will set these automatically. By * default the resource manager loads a new instance of the driver so * if your reader does not have more than one smartcard slot then * ignore the Lun in all the functions. Future versions of PC/SC might * support loading multiple readers through one instance of the driver * in which XXXX would be important to implement if you want this. */ /* * Channel - Channel ID. This is denoted by the following: * 0x000001 - /dev/pcsc/1 * 0x000002 - /dev/pcsc/2 * 0x000003 - /dev/pcsc/3 * 0x000004 - /dev/pcsc/4 * * USB readers may choose to ignore this parameter and query the bus * for the particular reader. */ /* * This function is required to open a communications channel to the * port listed by Channel. For example, the first serial reader on * COM1 would link to /dev/pcsc/1 which would be a sym link to * /dev/ttyS0 on some machines This is used to help with intermachine * independance. * * Once the channel is opened the reader must be in a state in which * it is possible to query IFDHICCPresence() for card status. * * returns: * * IFD_SUCCESS IFD_COMMUNICATION_ERROR */ RESPONSECODE return_value = IFD_SUCCESS; DEBUG_INFO3("lun: %lX, channel: %ld", Lun, Channel); if (iLunCheck(Lun)) return IFD_COMMUNICATION_ERROR; /* Reset ATR buffer */ pgSlots[LunToReaderIndex(Lun)].nATRLength = 0; *pgSlots[LunToReaderIndex(Lun)].pcATRBuffer = '\0'; /* Reset PowerFlags */ pgSlots[LunToReaderIndex(Lun)].bPowerFlags = POWERFLAGS_RAZ; if (OpenPort(Lun, Channel) != IFD_SUCCESS) { DEBUG_CRITICAL("OpenReader failed"); return_value = IFD_COMMUNICATION_ERROR; } return return_value; } /* IFDHCreateChannel */ RESPONSECODE IFDHCloseChannel(DWORD Lun) { /* * This function should close the reader communication channel for the * particular reader. Prior to closing the communication channel the * reader should make sure the card is powered down and the terminal * is also powered down. * * returns: * * IFD_SUCCESS IFD_COMMUNICATION_ERROR */ DEBUG_INFO2("lun: %lX", Lun); if (iLunCheck(Lun)) return IFD_COMMUNICATION_ERROR; GCCmdPowerDown(Lun); /* No reader status check, if it failed, what can you do ? :) */ ClosePort(Lun); return IFD_SUCCESS; } /* IFDHCloseChannel */ RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag, PDWORD Length, PUCHAR Value) { /* * This function should get the slot/card capabilities for a * particular slot/card specified by Lun. Again, if you have only 1 * card slot and don't mind loading a new driver for each reader then * ignore Lun. * * Tag - the tag for the information requested example: TAG_IFD_ATR - * return the Atr and it's size (required). these tags are defined in * ifdhandler.h * * Length - the length of the returned data Value - the value of the * data * * returns: * * IFD_SUCCESS IFD_ERROR_TAG */ DEBUG_INFO3("lun: %lX, tag: %lX", Lun, Tag); if (iLunCheck(Lun)) return IFD_COMMUNICATION_ERROR; switch (Tag) { case TAG_IFD_ATR: /* If Length is not zero, powerICC has been performed. * Otherwise, return NULL pointer * Buffer size is stored in *Length */ *Length = (*Length < pgSlots[LunToReaderIndex(Lun)].nATRLength) ? *Length : pgSlots[LunToReaderIndex(Lun)].nATRLength; if (*Length) memcpy(Value, pgSlots[LunToReaderIndex(Lun)].pcATRBuffer, *Length); break; case TAG_IFD_SIMULTANEOUS_ACCESS: if (*Length >= 1) { *Length = 1; *Value = PCSCLITE_MAX_READERS; } break; default: return IFD_ERROR_TAG; } return IFD_SUCCESS; } /* IFDHGetCapabilities */ RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag, DWORD Length, PUCHAR Value) { /* * This function should set the slot/card capabilities for a * particular slot/card specified by Lun. Again, if you have only 1 * card slot and don't mind loading a new driver for each reader then * ignore Lun. * * Tag - the tag for the information needing set * * Length - the length of the returned data Value - the value of the * data * * returns: * * IFD_SUCCESS IFD_ERROR_TAG IFD_ERROR_SET_FAILURE * IFD_ERROR_VALUE_READ_ONLY */ /* By default, say it worked */ DEBUG_PERIODIC3("lun: %lX, tag: %lX", Lun, Tag); (void)Length; (void)Value; if (iLunCheck(Lun)) return IFD_COMMUNICATION_ERROR; return IFD_SUCCESS; } /* IFDHSetCapabilities */ RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol, UCHAR Flags, UCHAR PTS1, UCHAR PTS2, UCHAR PTS3) { /* * This function should set the PTS of a particular card/slot using * the three PTS parameters sent * * Protocol - 0 .... 14 T=0 .... T=14 Flags - Logical OR of possible * values: IFD_NEGOTIATE_PTS1 IFD_NEGOTIATE_PTS2 IFD_NEGOTIATE_PTS3 to * determine which PTS values to negotiate. PTS1,PTS2,PTS3 - PTS * Values. * * returns: * * IFD_SUCCESS IFD_ERROR_PTS_FAILURE IFD_COMMUNICATION_ERROR * IFD_PROTOCOL_NOT_SUPPORTED */ DEBUG_INFO2("lun: %lX", Lun); (void)Protocol; (void)Flags; (void)PTS1; (void)PTS2; (void)PTS3; if (iLunCheck(Lun)) return IFD_COMMUNICATION_ERROR; return IFD_SUCCESS; } /* IFDHSetProtocolParameters */ RESPONSECODE IFDHPowerICC(DWORD Lun, DWORD Action, PUCHAR Atr, PDWORD AtrLength) { /* * This function controls the power and reset signals of the smartcard * reader at the particular reader/slot specified by Lun. * * Action - Action to be taken on the card. * * IFD_POWER_UP - Power and reset the card if not done so (store the * ATR and return it and it's length). * * IFD_POWER_DOWN - Power down the card if not done already * (Atr/AtrLength should be zero'd) * * IFD_RESET - Perform a quick reset on the card. If the card is not * powered power up the card. (Store and return the Atr/Length) * * Atr - Answer to Reset of the card. The driver is responsible for * caching this value in case IFDHGetCapabilities is called requesting * the ATR and it's length. This should not exceed MAX_ATR_SIZE. * * AtrLength - Length of the Atr. This should not exceed * MAX_ATR_SIZE. * * Notes: * * Memory cards without an ATR should return IFD_SUCCESS on reset but * the Atr should be zero'd and the length should be zero * * Reset errors should return zero for the AtrLength and return * IFD_ERROR_POWER_ACTION. * * returns: * * IFD_SUCCESS IFD_ERROR_POWER_ACTION IFD_COMMUNICATION_ERROR * IFD_NOT_SUPPORTED */ DWORD nlength; RESPONSECODE return_value = IFD_SUCCESS; UCHAR pcbuffer[RESP_BUF_SIZE]; DEBUG_INFO2("lun: %lX", Lun); /* By default, assume it won't work :) */ *AtrLength = 0; if (iLunCheck(Lun)) return IFD_COMMUNICATION_ERROR; switch (Action) { case IFD_POWER_UP: case IFD_RESET: nlength = sizeof(pcbuffer); if ((return_value = GCCmdPowerUp(Lun, &nlength, pcbuffer)) != IFD_SUCCESS) { DEBUG_CRITICAL("PowerUp failed"); goto end; } /* Power up successful, set state variable to memorise it */ pgSlots[LunToReaderIndex(Lun)].bPowerFlags |= MASK_POWERFLAGS_PUP; pgSlots[LunToReaderIndex(Lun)].bPowerFlags &= ~MASK_POWERFLAGS_PDWN; /* Reset is returned, even if TCK is wrong */ pgSlots[LunToReaderIndex(Lun)].nATRLength = *AtrLength = (nlength < MAX_ATR_SIZE) ? nlength : MAX_ATR_SIZE; memcpy(Atr, pcbuffer, *AtrLength); memcpy(pgSlots[LunToReaderIndex(Lun)].pcATRBuffer, pcbuffer, *AtrLength); break; case IFD_POWER_DOWN: /* Clear ATR buffer */ pgSlots[LunToReaderIndex(Lun)].nATRLength = 0; *pgSlots[LunToReaderIndex(Lun)].pcATRBuffer = '\0'; /* Memorise the request */ pgSlots[LunToReaderIndex(Lun)].bPowerFlags |= MASK_POWERFLAGS_PDWN; /* send the command */ return_value = GCCmdPowerDown(Lun); break; default: DEBUG_CRITICAL("Action not supported"); return_value = IFD_NOT_SUPPORTED; } end: return return_value; } /* IFDHPowerICC */ RESPONSECODE IFDHTransmitToICC(DWORD Lun, SCARD_IO_HEADER SendPci, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength, PSCARD_IO_HEADER RecvPci) { /* * This function performs an APDU exchange with the card/slot * specified by Lun. The driver is responsible for performing any * protocol specific exchanges such as T=0/1 ... differences. Calling * this function will abstract all protocol differences. * * SendPci Protocol - 0, 1, .... 14 Length - Not used. * * TxBuffer - Transmit APDU example (0x00 0xA4 0x00 0x00 0x02 0x3F * 0x00) TxLength - Length of this buffer. RxBuffer - Receive APDU * example (0x61 0x14) RxLength - Length of the received APDU. This * function will be passed the size of the buffer of RxBuffer and this * function is responsible for setting this to the length of the * received APDU. This should be ZERO on all errors. The resource * manager will take responsibility of zeroing out any temporary APDU * buffers for security reasons. * * RecvPci Protocol - 0, 1, .... 14 Length - Not used. * * Notes: The driver is responsible for knowing what type of card it * has. If the current slot/card contains a memory card then this * command should ignore the Protocol and use the MCT style commands * for support for these style cards and transmit them appropriately. * If your reader does not support memory cards or you don't want to * then ignore this. * * RxLength should be set to zero on error. * * returns: * * IFD_SUCCESS IFD_COMMUNICATION_ERROR IFD_RESPONSE_TIMEOUT * IFD_ICC_NOT_PRESENT IFD_PROTOCOL_NOT_SUPPORTED */ DWORD ntestlength; RESPONSECODE return_value = IFD_SUCCESS; /* Assume it will work */ DWORD protocol; DEBUG_INFO2("lun: %lX", Lun); (void)RecvPci; if (iLunCheck(Lun)) return IFD_COMMUNICATION_ERROR; protocol = SendPci.Protocol; /* if the reader is in EMV mode use ISO_EXCHANGE instead of ISO_INPUT * and ISO_OUTPUT. This is done with T=1 protocol */ if (pgSlots[LunToReaderIndex(Lun)].bPowerFlags & MASK_POWERFLAGS_EMV) protocol = T_1; switch (protocol) { case T_0: /* Check if command is going to fit in buffer */ if (CMD_BUF_SIZE < (GC_SIZE_CMD + TxLength)) { /* Buffer too small, send an error */ return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } /* Check if this is an incoming or outgoing command * Size should be command + one byte of length for * an outgoing TPDU (CLA, INS, P1, P2, P3) */ if (TxLength == (ISO_CMD_SIZE + ISO_LENGTH_SIZE)) { return_value = gemcore_ISO_OUTPUT_processing(Lun, TxBuffer, TxLength, RxBuffer, RxLength); break; } else { /* just (CLA, INS, P1, P2) for an APDU */ if (TxLength == ISO_CMD_SIZE) { unsigned char cmd[ISO_CMD_SIZE + ISO_LENGTH_SIZE]; /* copy CLA, INS, P1, P2 */ memcpy(cmd, TxBuffer, ISO_CMD_SIZE); /* set P3 to 0 */ cmd[ISO_CMD_SIZE] = 0; return_value = gemcore_ISO_INPUT_processing(Lun, cmd, ISO_CMD_SIZE + ISO_LENGTH_SIZE, RxBuffer, RxLength); } else { if (TxLength > (ISO_CMD_SIZE + ISO_LENGTH_SIZE)) { /* Check length to see if it is a full APDU or a TPDU */ ntestlength = TxBuffer[ISO_OFFSET_LENGTH] + ISO_CMD_SIZE + ISO_LENGTH_SIZE; if (TxLength == (ntestlength + ISO_LENGTH_SIZE)) { /* TxBuffer holds a proper APDU */ return_value = gemcore_ISO_EXCHANGE_processing(Lun, TxBuffer, TxLength, RxBuffer, RxLength); break; } else if (TxLength > (ntestlength + ISO_LENGTH_SIZE)) { /* Data are too long */ return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } /* Incoming TPDU */ return_value = gemcore_ISO_INPUT_processing(Lun, TxBuffer, TxLength, RxBuffer, RxLength); } else { /* TxBuffer holds too little data to form an APDU+length */ return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } } } break; case T_1: /* Check if command is going to fit in buffer * cmd byte + TxLength + Le */ if (CMD_BUF_SIZE < (GC_SIZE_CMD + TxLength + ISO_LENGTH_SIZE)) { /* Buffer too small, send an error */ return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } return_value = gemcore_ISO_EXCHANGE_processing(Lun, TxBuffer, TxLength, RxBuffer, RxLength); break; default: return_value = IFD_PROTOCOL_NOT_SUPPORTED; } clean_up_and_return: if (return_value != IFD_SUCCESS) *RxLength = 0; return return_value; } /* IFDHTransmitToICC */ RESPONSECODE IFDHControl(DWORD Lun, DWORD ControlCode, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, PDWORD pdwBytesReturned) { /* * This function performs a data exchange with the reader (not the * card) specified by Lun. Here XXXX will only be used. It is * responsible for abstracting functionality such as PIN pads, * biometrics, LCD panels, etc. You should follow the MCT, CTBCS * specifications for a list of accepted commands to implement. * * TxBuffer - Transmit data TxLength - Length of this buffer. RxBuffer * - Receive data RxLength - Length of the received data. This * function will be passed the length of the buffer RxBuffer and it * must set this to the length of the received data. * * Notes: RxLength should be zero on error. */ DEBUG_INFO2("lun: %lX", Lun); (void)ControlCode; (void)TxBuffer; (void)TxLength; (void)RxBuffer; (void)RxLength; /* this function is unsupported */ *pdwBytesReturned = 0; return IFD_COMMUNICATION_ERROR; } /* IFDHControl */ RESPONSECODE IFDHICCPresence(DWORD Lun) { /* * This function returns the status of the card inserted in the * reader/slot specified by Lun. It will return either: * * returns: IFD_ICC_PRESENT IFD_ICC_NOT_PRESENT * IFD_COMMUNICATION_ERROR */ UCHAR pcbuffer[GC_SIZE_CARD_STATUS]; RESPONSECODE return_value = IFD_COMMUNICATION_ERROR; DWORD length; DEBUG_PERIODIC2("lun: %lX", Lun); if (iLunCheck(Lun)) return IFD_COMMUNICATION_ERROR; length = sizeof(pcbuffer); if (GCCmdCardStatus(Lun, pcbuffer, &length) != IFD_SUCCESS) { DEBUG_CRITICAL("GCCmdCardStatus failed"); return_value = IFD_COMMUNICATION_ERROR; goto clean_up_and_return; } if (GC_MASK_ICC_PRESENCE & pcbuffer[GC_OFFSET_STAT_BYTE]) { /* Card is present, but is it powered-up? */ if (GC_MASK_POWER & pcbuffer[GC_OFFSET_STAT_BYTE]) { DEBUG_PERIODIC("Card present and powered"); /* Powered, so the ressource manager did not miss a quick * removal/re-insertion */ return_value = IFD_ICC_PRESENT; goto clean_up_and_return; } else { /* Card present but not powered up * Check if a power down has been requested */ if (pgSlots[LunToReaderIndex(Lun)].bPowerFlags & MASK_POWERFLAGS_PDWN) { DEBUG_PERIODIC("Card present not powered, power down requested"); /* Powerdown requested, so situation is normal */ return_value = IFD_ICC_PRESENT; goto clean_up_and_return; } /* Card inserted, not powered on but power down has not been * requested * Has the card been powered up already? */ if (pgSlots[LunToReaderIndex(Lun)].bPowerFlags & MASK_POWERFLAGS_PUP) { DEBUG_PERIODIC("Card pull-out+re-insert detected CARD OUT SIMULATION"); /* Power-up has been requested, but not power down and power is * down. This should happen only if the card has been pulled * out and reinserted too quickly for the resource manager to * realise. A card out event is therefore simulated. Clear ATR * buffer */ pgSlots[LunToReaderIndex(Lun)].nATRLength = 0; *pgSlots[LunToReaderIndex(Lun)].pcATRBuffer = '\0'; /* reset power flags */ pgSlots[LunToReaderIndex(Lun)].bPowerFlags = POWERFLAGS_RAZ; return_value = IFD_ICC_NOT_PRESENT; goto clean_up_and_return; } DEBUG_PERIODIC("Card present, just inserted"); /* If control gets here, the card is in, not powered on, with * no power down request and no previous power up request * it is therefore a card insertion event */ pgSlots[LunToReaderIndex(Lun)].nATRLength = 0; *pgSlots[LunToReaderIndex(Lun)].pcATRBuffer = '\0'; /* reset power flags */ pgSlots[LunToReaderIndex(Lun)].bPowerFlags = POWERFLAGS_RAZ; return_value = IFD_ICC_PRESENT; goto clean_up_and_return; } } else { DEBUG_PERIODIC("Card absent"); /* Clear ATR buffer */ pgSlots[LunToReaderIndex(Lun)].nATRLength = 0; *pgSlots[LunToReaderIndex(Lun)].pcATRBuffer = '\0'; /* Card removed, clear the flags */ pgSlots[LunToReaderIndex(Lun)].bPowerFlags = POWERFLAGS_RAZ; return_value = IFD_ICC_NOT_PRESENT; } clean_up_and_return: return return_value; } /* IFDHICCPresence */ void IFDSetEmv(DWORD lun) { pgSlots[LunToReaderIndex(lun)].bPowerFlags |= MASK_POWERFLAGS_EMV; } /* IFDSetEmv */ ifd-gempc-1.0.7/common/Makefile0000644000175000017500000000072510561621137016606 0ustar rousseaurousseau# $Id: Makefile,v 1.17 2003-08-14 09:45:18 rousseau Exp $ OBJS = GCCmds.o GCUtils.o ifdhandler.o GCdebug.o all: $(OBJS) clean: rm -f $(OBJS) rm -f .dependencies touch .dependencies distclean: clean rm -f tags rm -f dep_stamp ctags: ctags-exuberant *.h *.c dep: dep_stamp dep_stamp: makedepend -f - -I. -I../GemPC410 -DGEMPC=410 *.c > .dependencies || true touch dep_stamp .dependencies: dep .PHONY: all clean distclean ctags dep include .dependencies ifd-gempc-1.0.7/common/GCdebug.h0000644000175000017500000000406111740361173016615 0ustar rousseaurousseau/* * $Id: GCdebug.h,v 1.13 2012/04/08 19:09:47 rousseau Exp $ * gcdebug.h: log (or not) messages using syslog * Copyright (C) 2001 Ludovic Rousseau * * License: this code is under a double licence COPYING.BSD and COPYING.GPL * */ /* * DEBUG_CRITICAL("text"); * print "text" is DEBUG_LEVEL_CRITICAL and DEBUG_STDERR is defined * send "text" to syslog if DEBUG_LEVEL_CRITICAL is defined * * DEBUG_CRITICAL2("text: %d", 1234) * print "text: 1234" is DEBUG_LEVEL_CRITICAL and DEBUG_STDERR is defined * send "text: 1234" to syslog if DEBUG_LEVEL_CRITICAL is defined * the format string can be anything printf() can understand * * same thing for DEBUG_INFO and DEBUG_COMM * * DEBUG_XXD(msg, buffer, size) is only defined if DEBUG_LEVEL_COMM if defined * */ #ifndef __CONFIG_H__ #error "file Config.h NOT included" #endif #ifdef __APPLE__ #include #else #include #endif #ifndef _GCDEBUG_H_ #define _GCDEBUG_H_ /* You can't do #ifndef __FUNCTION__ */ #if !defined(__GNUC__) && !defined(__IBMC__) #define __FUNCTION__ "" #endif #define DEBUG_CRITICAL(fmt) Log1(PCSC_LOG_CRITICAL, fmt) #define DEBUG_CRITICAL2(fmt, data) Log2(PCSC_LOG_CRITICAL, fmt, data) #define DEBUG_CRITICAL3(fmt, data1, data2) Log3(PCSC_LOG_CRITICAL, fmt, data1, data2) #define DEBUG_CRITICAL4(fmt, data1, data2, data3) Log4(PCSC_LOG_CRITICAL, fmt, data1, data2, data3) #define DEBUG_INFO(fmt) Log1(PCSC_LOG_INFO, fmt) #define DEBUG_INFO2(fmt, data) Log2(PCSC_LOG_INFO, fmt, data) #define DEBUG_INFO3(fmt, data1, data2) Log3(PCSC_LOG_INFO, fmt, data1, data2) #define DEBUG_PERIODIC(fmt) Log1(PCSC_LOG_DEBUG, fmt) #define DEBUG_PERIODIC2(fmt, data) Log2(PCSC_LOG_DEBUG, fmt, data) #define DEBUG_PERIODIC3(fmt, data1, data2) Log3(PCSC_LOG_DEBUG, fmt, data1, data2) #define DEBUG_COMM(fmt) Log1(PCSC_LOG_DEBUG, fmt) #define DEBUG_COMM2(fmt, data) Log2(PCSC_LOG_DEBUG, fmt, data) #define DEBUG_COMM3(fmt, data1, data2) Log3(PCSC_LOG_DEBUG, fmt, data1, data2) #define DEBUG_XXD(msg, buffer, size) log_xxd(PCSC_LOG_DEBUG, msg, buffer, size) #endif ifd-gempc-1.0.7/check0000755000175000017500000001163111716546414014666 0ustar rousseaurousseau#!/bin/sh # check: verify all the needed parts are present # Copyright (C) 2002-2004 Ludovic Rousseau # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # this code is greatly inspired by configure scripts generated by autoconf # $Id: check,v 1.10 2006/02/09 13:28:25 rousseau Exp $ exec 5>./config.log CHECK_CFLAGS=`pkg-config libpcsclite --cflags` ac_ext=c ac_cpp='cpp $CFLAGS $CHECK_CFLAGS' ac_cc=cc ac_compile='${CC-cc} -c $CFLAGS $CHECK_CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CHECK_CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' # test the presence of a .h file # the filename to check is fetched from $ac_hdr check_h() { ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo -n "checking for $ac_hdr""... " echo "checking for $ac_hdr""... " >&5 cat > conftest.${ac_ext} << EOF #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 echo $ac_try >& 5 cat conftest.out >& 5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "yes" else echo "no" fi } # check the presence of pcsclite.h ac_hdr="pcsclite.h" check_h if [ "$ac_cv_header_pcsclite_h" = "no" ] then cat << EOF FILE MISSING! You must install the pcsc-lite software before compiling this software You can get it from http://pcsclite.alioth.debian.org/ or from a package of your operating system distribution If pcsc-lite is already installed but not in /usr/ or /usr/local/ you must edit GemPC4?0/Makefile and change the definition of INCS. EOF exit 1 fi # check the version of pcsc-lite ac_version=\"1.2.9-beta7\" ac_hdr=pcsclite.h ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo -n "checking for pcsc-lite version >= $ac_version... " echo "checking for pcsc-lite version >= $ac_version... " >&5 cat > conftest.${ac_ext} << EOF #include #include <$ac_hdr> int main() { if (strcmp(PCSCLITE_VERSION_NUMBER, $ac_version) < 0) { char cpcsc[] = PCSCLITE_VERSION_NUMBER; char cdriver[] = $ac_version; /* compare "1.2.9-beta" */ if (strncmp(cpcsc, cdriver, 10) == 0) { int p, v; p = atoi(cpcsc+10); v = atoi(cdriver+10); if (v<=p) return 0; } return 1; } else return 0; } EOF if { (eval $ac_link) 2>&5; } && ./conftest; then eval "ac_cv_pcsc_version=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 eval "ac_cv_pcsc_version=no" fi rm -f conftest* if eval "test \"`echo '$ac_cv_'pcsc_version`\" = yes"; then echo "yes" : else echo "no" fi if [ $ac_cv_pcsc_version = "no" ] then cat << EOF WRONG VERSION OF PCSC-LITE! You can get it from http://pcsclite.alioth.debian.org/ or from a package of your operating system distribution EOF exit 1 fi # if we test for a GemPC410 we stop here if [ "$1" = 410 ] then exit 0 fi # check the presence of usb.h ac_hdr=usb.h check_h if [ $ac_cv_header_usb_h = "no" ] then cat << EOF FILE MISSING! You must install the libusb library before compiling this software You can get it from http://libusb.sourceforge.net/ or from a package of your operating system distribution EOF exit 1 fi # check the presence of usb_get_busses() LDFLAGS="$LDFLAGS -lusb" echo -n "checking for usb_get_busses... " echo "checking for usb_get_busses... " >&5 cat > conftest.$ac_ext <&5; } && test -s conftest; then eval "ac_cv_func_usb_get_busses=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 eval "ac_cv_func_usb_get_busses=no" fi rm -f conftest* if eval "test \"`echo '$ac_cv_func_'usb_get_busses`\" = yes"; then echo "yes" : else echo "no" fi if [ $ac_cv_func_usb_get_busses = "no" ] then cat << EOF WRONG VERSION OF LIBUSB! Your version of libusb is not correct (too old?). You must use version 0.1.6a or superior. You can get it from http://libusb.sourceforge.net/ or from a package of your operating system distribution EOF exit 1 fi exit 0 ifd-gempc-1.0.7/create_distrib.sh0000755000175000017500000000361510561621046017200 0ustar rousseaurousseau#!/bin/bash -e # $Id: create_distrib.sh,v 1.7 2002-09-07 13:04:39 rousseau Exp $ # create a new directory named after the current directory name # the directory name should be in the form foo-bar.x.y.z # the use of "_" is not recommanded since it is a problem for Debian dir=$(basename $(pwd)) echo -e "Using $dir as directory name\n" rv=$(echo $dir | sed -e 's/.*-[0-9]\+\.[0-9]\+\.[0-9]\+/ok/') if [ $rv != "ok" ] then echo "ERROR: The directory name should be in the form foo-bar-x.y.z" exit fi if [ -e $dir ] then echo -e "ERROR: $dir already exists\nremove it and restart" exit fi # check the Config.h files grep "^#define DEBUG_LEVEL_PERIODIC" GemPC410/Config.h && exit grep "^#define DEBUG_LEVEL_PERIODIC" GemPC430/Config.h && exit grep "^#define DEBUG_LEVEL_COMM" GemPC410/Config.h && exit grep "^#define DEBUG_LEVEL_COMM" GemPC430/Config.h && exit # clean echo -n "cleaning..." make distclean &> /dev/null echo "done" # generate Changelog rcs2log > Changelog present_files=$(tempfile) manifest_files=$(tempfile) diff_result=$(tempfile) # find files present # remove ^debian and ^create_distrib.sh find -type f | grep -v CVS | cut -c 3- | sort > $present_files cat MANIFEST | sort > $manifest_files # diff the two lists diff $present_files $manifest_files | grep '<' | cut -c 2- > $diff_result if [ -s $diff_result ] then echo -e "WARGING! some files will not be included in the archive.\nAdd them in MANIFEST" cat $diff_result echo fi # remove temporary files rm $present_files $manifest_files $diff_result # create the temporary directory mkdir $dir function at_exit() { rm -r $dir } trap at_exit EXIT for i in $(cat MANIFEST) do if [ $(echo $i | grep /) ] then idir=$dir/${i%/*} if [ ! -d $idir ] then echo "mkdir $idir" mkdir -p $idir fi fi echo "cp $i $dir/$i" cp -a $i $dir/$i done tar czvf ../$dir.tar.gz $dir # the rm is done by the at_exit function #rm -r $dir exit ifd-gempc-1.0.7/Makefile0000644000175000017500000000100510561621030015276 0ustar rousseaurousseau# $Id: Makefile,v 1.9 2003-05-03 07:43:49 rousseau Exp $ all: $(MAKE) -C common clean $(MAKE) -C GemPC410 $(MAKE) -C common clean $(MAKE) -C GemPC430 clean: $(MAKE) -C GemPC410 clean $(MAKE) -C GemPC430 clean $(MAKE) -C common clean distclean: $(MAKE) -C GemPC410 distclean $(MAKE) -C GemPC430 distclean $(MAKE) -C common distclean rm -f config.log install: $(MAKE) -C common clean $(MAKE) -C GemPC410 install $(MAKE) -C common clean $(MAKE) -C GemPC430 install .PHONY: all clean distclean ctags