New upstream version 1.5.0
This commit is contained in:
parent
3d895c8b7c
commit
d964627ccc
948
ChangeLog
948
ChangeLog
|
@ -1,4 +1,948 @@
|
||||||
commit 74642f87f9e1a937e807acd3a7d2ef600b8d151c (HEAD -> master, zotac/master, origin/master, origin/HEAD)
|
commit f79106c365ed0747109e7e465adb54bf176b1036 (HEAD -> master, tag: 1.5.0, zotac/master, origin/master, origin/HEAD, github/master)
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Thu Jan 27 11:24:13 2022 +0100
|
||||||
|
|
||||||
|
Release 1.5.0
|
||||||
|
|
||||||
|
Signed-off-by: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
|
||||||
|
README.md | 26 ++++++++++++++++++++++++++
|
||||||
|
configure.ac | 2 +-
|
||||||
|
2 files changed, 27 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit 401f9fba36be17592188713f29559c1bf616bde4
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Thu Jan 27 12:50:23 2022 +0100
|
||||||
|
|
||||||
|
ReadUSB: Fix compiler warning
|
||||||
|
|
||||||
|
ccid_usb.c: In function ‘ReadUSB’:
|
||||||
|
ccid_usb.c:967:61: warning: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Wsign-compare]
|
||||||
|
967 | if (concurrent[slot].length > *length)
|
||||||
|
|
||||||
|
src/ccid_usb.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit 9c59fc5557c5ac515f87f877fb5a337166b33343
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Thu Jan 27 11:10:22 2022 +0100
|
||||||
|
|
||||||
|
Add Thales Shield M4 Reader
|
||||||
|
|
||||||
|
readers/Thales_Shield_M4_Reader.txt | 56 +++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 5 +++-
|
||||||
|
2 files changed, 60 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit a725a113ee050a5b0e336dca44bbff035786ee16
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Fri Jan 21 11:12:05 2022 +0100
|
||||||
|
|
||||||
|
Multi_ReadProc() exits on the *last* slot exit
|
||||||
|
|
||||||
|
The function to read data from multi-slots readers should exit only when
|
||||||
|
the last slot is terminated.
|
||||||
|
|
||||||
|
Before the change, the function was terminated with the _first_ slot. So
|
||||||
|
it was not possible to send PowerDown commands to the other slots of the
|
||||||
|
same reader.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 8 ++++++--
|
||||||
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
commit 5583333cdb6f30684c8eb569761516ed49c61ec3
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 19 15:17:46 2022 +0100
|
||||||
|
|
||||||
|
Prevent a potential buffer overflow for concurrent multi-slots
|
||||||
|
|
||||||
|
Check the buffer is large enough to copy all the received bytes.
|
||||||
|
The problem should never happen in practice but...
|
||||||
|
|
||||||
|
src/ccid_usb.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit 1addd756eeb182764fc55a95a9fe1a8af35da805
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sat Nov 6 14:12:19 2021 +0100
|
||||||
|
|
||||||
|
Check the bSeq value when receiving a CCID frame
|
||||||
|
|
||||||
|
For multi-slots readers we now use a different USB read routine.
|
||||||
|
We can now get USB packets that were waiting in the reader but not yet
|
||||||
|
sent. For example this happens when pcscd is stopped and restarted.
|
||||||
|
On restart the driver will receive packets that were not yet read during
|
||||||
|
the previous execution of pcscd.
|
||||||
|
|
||||||
|
We must ignore packets with a bSeq that does not correspond to the bSeq
|
||||||
|
of the command sent by the reader.
|
||||||
|
|
||||||
|
src/ccid_serial.c | 5 ++++-
|
||||||
|
src/ccid_serial.h | 2 +-
|
||||||
|
src/ccid_usb.c | 8 ++++----
|
||||||
|
src/ccid_usb.h | 2 +-
|
||||||
|
src/commands.c | 32 +++++++++++++++++++++-----------
|
||||||
|
5 files changed, 31 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
commit 77376bcefff4831894033f6e06ee95764afa02bd
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Oct 31 14:49:43 2021 +0100
|
||||||
|
|
||||||
|
Multi_ReadProc: wait for 100 ms in case of libusb error
|
||||||
|
|
||||||
|
We wait a bit to avoid a fast error loop.
|
||||||
|
If libusb_bulk_transfer() failed because the device has been removed
|
||||||
|
then the device will stay removed and we may fill the logs with error
|
||||||
|
messages untill the removal is detected and reported by pcscd hotplug
|
||||||
|
mechanism.
|
||||||
|
|
||||||
|
The only case in which we do NOT wait is LIBUSB_ERROR_TIMEOUT because
|
||||||
|
this case is expected and we should wait again immediatly.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
commit 298903c8f85cb0e79aeddd6cc7ff50d2829397db
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Oct 27 18:33:40 2021 +0200
|
||||||
|
|
||||||
|
Enable TAG_IFD_SLOT_THREAD_SAFE when supported
|
||||||
|
|
||||||
|
We only support the case of readers that can support access to all slots
|
||||||
|
at the same time. That is the case of the sysmoOCTSIM for example.
|
||||||
|
|
||||||
|
But if the reader can only support a subset of the slot at the same time
|
||||||
|
we continue as before. That is the case of the COVADIS Auriga that
|
||||||
|
declares 3 slots but can only have 2 slots active at the same time.
|
||||||
|
|
||||||
|
src/ifdhandler.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit 47fd21e31bec8e068910dfb03f6123cc9d3faacf
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Jan 23 10:32:04 2022 +0100
|
||||||
|
|
||||||
|
Add suport of simultaneous slot access
|
||||||
|
|
||||||
|
This is used for multi slots readers like the sysmoOCTSIM reader with 8
|
||||||
|
slots.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
|
||||||
|
1 file changed, 199 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
commit 1fa58ab0363455523739c04146c96c84f33a029f
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Oct 27 15:52:42 2021 +0200
|
||||||
|
|
||||||
|
Store CCID field bMaxCCIDBusySlots
|
||||||
|
|
||||||
|
We will need this value to know the number of slots that can be used
|
||||||
|
simultanesously.
|
||||||
|
|
||||||
|
src/ccid.h | 5 +++++
|
||||||
|
src/ccid_serial.c | 1 +
|
||||||
|
src/ccid_usb.c | 1 +
|
||||||
|
3 files changed, 7 insertions(+)
|
||||||
|
|
||||||
|
commit d1cf6bdc73bfe056487432fcd949a7ab8b1e57a7
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sat Jan 22 17:32:47 2022 +0100
|
||||||
|
|
||||||
|
Multi_PollingProc: do not set .terminated here
|
||||||
|
|
||||||
|
The field .terminated is set to TRUE in Multi_PollingTerminate() to terminate
|
||||||
|
the thread.
|
||||||
|
|
||||||
|
This line was present since the initial patch
|
||||||
|
38faa97872a526e069a856df710167fe4c50486a in 2013.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
commit 0ee9dd19a6258a05553c66ec536325cae04c3341
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sat Jan 22 14:33:16 2022 +0100
|
||||||
|
|
||||||
|
Multi_PollingProc: allocate the libusb transfer once
|
||||||
|
|
||||||
|
No need to allocate/free the libusb transfer structure for each
|
||||||
|
transfer.
|
||||||
|
We do it once at the beginning of the function.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 25 ++++++++++---------------
|
||||||
|
1 file changed, 10 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
commit a2daf37ee1eaa84fc10a78114372e4eb588ac7ab
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Fri Jan 21 10:58:48 2022 +0100
|
||||||
|
|
||||||
|
Multi_PollingProc: log the status name instead of its value
|
||||||
|
|
||||||
|
Use libusb_error_name(status) to log a human readable text instead of a
|
||||||
|
numeric value.
|
||||||
|
We now have:
|
||||||
|
00000085 ccid_usb.c:1703:Multi_PollingProc() Multi_PollingProc (1/7): LIBUSB_TRANSFER_CANCELLED
|
||||||
|
instead of:
|
||||||
|
00000148 ccid_usb.c:1703:Multi_PollingProc() Multi_PollingProc (1/7): 3
|
||||||
|
|
||||||
|
src/ccid_usb.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
commit 5259925ceb74eca69b3aad7658df30d6fa938ed6
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Thu Jan 20 18:49:07 2022 +0100
|
||||||
|
|
||||||
|
IFDHSetProtocolParameters: always compute readTimeout
|
||||||
|
|
||||||
|
If the reader declares CCID_CLASS_AUTO_PPS_PROP the driver does not send
|
||||||
|
the PC_to_RDR_SetParameters CCID command.
|
||||||
|
But we must compute the readTimeout to use according to the card ATR.
|
||||||
|
|
||||||
|
The default read timeout of 3 seconds may not be a good value in every
|
||||||
|
cases.
|
||||||
|
|
||||||
|
The problem was detected using the SpringCard Puck One reader that does
|
||||||
|
NOT send time extension requests.
|
||||||
|
|
||||||
|
src/ifdhandler.c | 27 +++++++++++++++++----------
|
||||||
|
1 file changed, 17 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
commit 560de95fa73f426286aeab9c7191dfacc472bbed
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Jan 16 21:40:02 2022 +0100
|
||||||
|
|
||||||
|
Remore unused field "transfer"
|
||||||
|
|
||||||
|
The "struct usbDevice_MultiSlot_Extension" had a field
|
||||||
|
"struct libusb_transfer *transfer;" that was not used.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
commit 0e0141e05a3a1f05e116700e62a89d2c6c9e25b2
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 19 16:40:18 2022 +0100
|
||||||
|
|
||||||
|
Do not log the libusb error value, just its name
|
||||||
|
|
||||||
|
There is no real value to duplicate the libusb error name by the error
|
||||||
|
value.
|
||||||
|
"-4 LIBUSB_ERROR_NO_DEVICE" is not more informative than just
|
||||||
|
"LIBUSB_ERROR_NO_DEVICE".
|
||||||
|
|
||||||
|
src/ccid_usb.c | 20 +++++++++++---------
|
||||||
|
1 file changed, 11 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
commit 43050f337edb9d38a35dec04ee5448c74b19c272
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 19 16:24:43 2022 +0100
|
||||||
|
|
||||||
|
Do not log LIBUSB_ERROR_NO_DEVICE when a multi slot is removed
|
||||||
|
|
||||||
|
When a multi slot reader with simultaneous acces used is removed we get
|
||||||
|
the error log:
|
||||||
|
00000000 [140737321879104] ccid_usb.c:1734:Multi_PollingProc() Multi_PollingProc (1/18): error -4 LIBUSB_ERROR_NO_DEVICE
|
||||||
|
|
||||||
|
Since this error is expected we do not log it.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 14 ++++++++++----
|
||||||
|
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
commit 75f80160d71b0bbcb31b4b81a71e963ed0b35c09
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 19 13:43:17 2022 +0100
|
||||||
|
|
||||||
|
iInterruptRead: log libusb error text version
|
||||||
|
|
||||||
|
Log the libusb error name instead of just the decimal code.
|
||||||
|
|
||||||
|
In the logs we now have:
|
||||||
|
00000034 [139678897940032] ccid_usb.c:1526:InterruptRead() InterruptRead (1/7): LIBUSB_TRANSFER_CANCELLED
|
||||||
|
instead of :
|
||||||
|
00000034 [139678897940032] ccid_usb.c:1526:InterruptRead() InterruptRead (1/7): 3
|
||||||
|
|
||||||
|
src/ccid_usb.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
commit 100a4e910be1012f26fa771496bff5f9346f08f6
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 19 13:35:42 2022 +0100
|
||||||
|
|
||||||
|
Avoid potential data race for card events management
|
||||||
|
|
||||||
|
Declare polling_transfer field as _Atomic since it is accessed from
|
||||||
|
different threads.
|
||||||
|
|
||||||
|
The thread running InterruptRead() or Multi_PollingProc() has a
|
||||||
|
read/write access.
|
||||||
|
|
||||||
|
The thread running InterruptStop() or Multi_PollingTerminate() also
|
||||||
|
access the field to cancel the transfer.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 19 ++++++++++---------
|
||||||
|
1 file changed, 10 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
commit a6edf774c0a9d2d63c0fd2c939888dcedb3d2904
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 19 10:02:25 2022 +0100
|
||||||
|
|
||||||
|
Avoid potential data race for multi-slots readers
|
||||||
|
|
||||||
|
Declare "terminated" field as _Atomic since it is accessed from
|
||||||
|
different threads: one thread reads the value and the value is set from
|
||||||
|
another thread to indicate to the first thread to exit.
|
||||||
|
|
||||||
|
I have NOT found an occurence of the bug in a real execution. But the
|
||||||
|
code should be safer now.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
commit 51d90a5e0f1d1d9abc420207b5543ea50707d6c1
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 19 15:09:25 2022 +0100
|
||||||
|
|
||||||
|
Rewrite DEBUG_*() macros
|
||||||
|
|
||||||
|
Wrap the code in a "do { [...] } while(0)" so it is possible to use a
|
||||||
|
construct like:
|
||||||
|
if (condition)
|
||||||
|
DEBUG_CRITICAL("Error");
|
||||||
|
else
|
||||||
|
normal execution
|
||||||
|
|
||||||
|
Before the change, the DEBUG_CRITICAL() was expanded to:
|
||||||
|
if (condition)
|
||||||
|
if (LogLevel & DEBUG_LEVEL_CRITICAL)
|
||||||
|
Log1(PCSC_LOG_CRITICAL, fmt)
|
||||||
|
else
|
||||||
|
normal execution
|
||||||
|
So the "else" was associated to the second "if" instead of the first
|
||||||
|
one.
|
||||||
|
And this is an open door for bugs.
|
||||||
|
|
||||||
|
To avoid any problem the code should have been:
|
||||||
|
if (condition)
|
||||||
|
{
|
||||||
|
DEBUG_CRITICAL("Error");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
normal execution
|
||||||
|
|
||||||
|
DEBUG_*() maros are now safer to use.
|
||||||
|
|
||||||
|
src/debug.h | 61 +++++++++++++++++++++++++++----------------------------------
|
||||||
|
1 file changed, 27 insertions(+), 34 deletions(-)
|
||||||
|
|
||||||
|
commit a6ed3fa1bdb554f3a0e01e9d9fb261d88ab298b2
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sat Jan 15 13:36:55 2022 +0100
|
||||||
|
|
||||||
|
IFDHSetProtocolParameters: harmonize log message
|
||||||
|
|
||||||
|
Use "Timeout:" for T=0 as for T=1 (line 1068) and when no computation
|
||||||
|
is done (line 816).
|
||||||
|
|
||||||
|
src/ifdhandler.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit 2ffdb61caee2921b5f6d5b2309ea9993e1ca557c
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 16:29:37 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CIR615 CL
|
||||||
|
|
||||||
|
readers/Circle_CIR615_CL.txt | 54 +++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 1 +
|
||||||
|
2 files changed, 55 insertions(+)
|
||||||
|
|
||||||
|
commit cf35f360ae11b1cfc4ed79de4d8a35beed7df144
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 16:28:24 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CIR615 CL & 1S
|
||||||
|
|
||||||
|
readers/Circle_CIR615_CL_1S.txt | 54 +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 1 +
|
||||||
|
2 files changed, 55 insertions(+)
|
||||||
|
|
||||||
|
commit c1f69339a3a5e9b214c809309f8a5c73e0cecf4d
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 16:24:48 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CIR515 ICC
|
||||||
|
|
||||||
|
readers/Circle_CIR515_ICC.txt | 54 +++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 1 +
|
||||||
|
2 files changed, 55 insertions(+)
|
||||||
|
|
||||||
|
commit f9768e1d61955ac630b66d6b57a3f88d33d3c16a
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 16:23:29 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CIR415 CL
|
||||||
|
|
||||||
|
readers/Circle_CIR415_CL.txt | 54 +++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 1 +
|
||||||
|
2 files changed, 55 insertions(+)
|
||||||
|
|
||||||
|
commit e90ea431d2fd731408efe384b2ba6c20b42d6a87
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 16:21:59 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CIR315 with idProduct: 0x7004
|
||||||
|
|
||||||
|
readers/Circle_CIR315_0x7004.txt | 105 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 1 +
|
||||||
|
2 files changed, 106 insertions(+)
|
||||||
|
|
||||||
|
commit 8ecaacb0aae32d9d21d09f88c076a90f4759357f
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 16:20:49 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CIR315 DI
|
||||||
|
|
||||||
|
readers/Circle_CIR315_DI.txt | 54 +++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 1 +
|
||||||
|
2 files changed, 55 insertions(+)
|
||||||
|
|
||||||
|
commit 868abf1248b45469496b2c73e8ac380a607f9241
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 16:19:19 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CIR315 with idProduct: 0x0324
|
||||||
|
|
||||||
|
readers/Circle_CIR315_0x0324.txt | 105 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 1 +
|
||||||
|
2 files changed, 106 insertions(+)
|
||||||
|
|
||||||
|
commit 472d0964c94a1113100a753a9cdd0103f75be5e5
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 16:14:24 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CIR215 CL with iProduct 0x2100
|
||||||
|
|
||||||
|
readers/Circle_CIR215_CL_0x2100.txt | 54 +++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 1 +
|
||||||
|
2 files changed, 55 insertions(+)
|
||||||
|
|
||||||
|
commit 0ca1dcd5bb80f46538f20f5226491356c8536d5a
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 15:53:13 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CIR125-DOT ICC
|
||||||
|
|
||||||
|
readers/Circle_CIR125-DOT_ICC.txt | 54 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 1 +
|
||||||
|
2 files changed, 55 insertions(+)
|
||||||
|
|
||||||
|
commit bec5918390dc052f49fc032868172602f91f81ba
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 15:51:16 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CCR7125 ICC
|
||||||
|
|
||||||
|
readers/Circle_CCR7125_ICC.txt | 54 ++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 1 +
|
||||||
|
2 files changed, 55 insertions(+)
|
||||||
|
|
||||||
|
commit 8fcb0d2066c405f5b348458aea4857dc27239215
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Jan 5 15:49:40 2022 +0100
|
||||||
|
|
||||||
|
Add Circle CIR125 ICC
|
||||||
|
|
||||||
|
readers/Circle_CIR125_ICC.txt | 54 +++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 3 ++-
|
||||||
|
2 files changed, 56 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit fdfa06b98637444f5ef1a4c50c5a520cc9b63f0f
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Nov 17 13:17:08 2021 +0100
|
||||||
|
|
||||||
|
ylwrap: update copyright date
|
||||||
|
|
||||||
|
ylwrap | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit abb793b270704b0a33f8027253015fc82abbf72e
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sat Nov 6 14:32:30 2021 +0100
|
||||||
|
|
||||||
|
IFDHPowerICC: do not log an error for IFD_NO_SUCH_DEVICE
|
||||||
|
|
||||||
|
When a reader is removed pcscd will try to cleanly close the driver and
|
||||||
|
will try to power down the card (if needed).
|
||||||
|
|
||||||
|
WriteUSB() will correctly return STATUS_NO_SUCH_DEVICE. CmdPowerOff()
|
||||||
|
will also return STATUS_NO_SUCH_DEVICE.
|
||||||
|
But IFDHPowerICC() did not correctly handled this returned value.
|
||||||
|
|
||||||
|
src/ifdhandler.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
commit 6ebc18e90fea92caf8d79765b08cd6f137100fbe
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sat Nov 6 13:57:17 2021 +0100
|
||||||
|
|
||||||
|
Revert "multi-slots: Start the sequence number at 0 for a new slot"
|
||||||
|
|
||||||
|
This reverts commit e3baafb89cee3eae9302e454ca25332401b9569c.
|
||||||
|
|
||||||
|
src/ccid_serial.c | 1 -
|
||||||
|
src/ccid_usb.c | 1 -
|
||||||
|
2 files changed, 2 deletions(-)
|
||||||
|
|
||||||
|
commit d1ee8371e47802dd41a86d9303074214fb7814df
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Oct 24 18:44:46 2021 +0200
|
||||||
|
|
||||||
|
Revert "Each slot has its own sequence number"
|
||||||
|
|
||||||
|
The Gemalto GemCore SIM Pro Smart Card Reader, that has 2 slots, does
|
||||||
|
not like to have the same bSeq used for 2 consecutive commands on 2
|
||||||
|
different slots. The reader does not answer to the second command. I
|
||||||
|
guess it considers the 2nd command as duplicate ghost or something like
|
||||||
|
that.
|
||||||
|
|
||||||
|
For example we get:
|
||||||
|
00000007 [140486031439616] ifdhandler.c:1209:IFDHPowerICC() action: PowerDown, usb:08
|
||||||
|
e6/3480:libudev:0:/dev/bus/usb/001/012 (lun: 0)
|
||||||
|
00000008 [140486031439616] -> 000000 63 00 00 00 00 00 04 00 00 00
|
||||||
|
00000257 [140486031439616] ccid_usb.c:948:ReadUSB() Waiting data for slot 0
|
||||||
|
00000320 [140486107440896] ccid_usb.c:1949:Multi_ReadProc() Read 10 bytes for slot 0
|
||||||
|
00000024 [140486107440896] ccid_usb.c:1957:Multi_ReadProc() Signaled reader 0 slot 0
|
||||||
|
00000005 [140486107440896] ccid_usb.c:1917:Multi_ReadProc() Waiting read for reader 0
|
||||||
|
00000076 [140486031439616] ccid_usb.c:962:ReadUSB() Got 10 bytes for slot 0
|
||||||
|
00000025 [140486031439616] <- 000000 81 00 00 00 00 00 04 01 00 00
|
||||||
|
00000008 [140486031439616] eventhandler.c:482:EHStatusHandlerThread() powerState: POW
|
||||||
|
ER_STATE_UNPOWERED
|
||||||
|
00000009 [140486031439616] ifdhandler.c:1915:IFDHICCPresence() usb:08e6/3480:libudev:
|
||||||
|
0:/dev/bus/usb/001/012 (lun: 0)
|
||||||
|
00000006 [140486031439616] ifdhandler.c:2041:IFDHICCPresence() Card present
|
||||||
|
00000007 [140486031439616] ifdhandler.c:317:IFDHPolling() usb:08e6/3480:libudev:0:/de
|
||||||
|
v/bus/usb/001/012 (lun: 0) 600000 ms
|
||||||
|
00000008 [140486031439616] ccid_usb.c:1801:Multi_InterruptRead() Multi_InterruptRead
|
||||||
|
(0), timeout: 600000 ms
|
||||||
|
00167330 [140486023046912] ifdhandler.c:1915:IFDHICCPresence() usb:08e6/3480:libudev:
|
||||||
|
0:/dev/bus/usb/001/012 (lun: 1)
|
||||||
|
00000026 [140486023046912] ifdhandler.c:2041:IFDHICCPresence() Card present
|
||||||
|
00000006 [140486023046912] ifdhandler.c:1209:IFDHPowerICC() action: PowerDown, usb:08
|
||||||
|
e6/3480:libudev:0:/dev/bus/usb/001/012 (lun: 1)
|
||||||
|
00000009 [140486023046912] -> 000001 63 00 00 00 00 01 04 00 00 00
|
||||||
|
00000260 [140486023046912] ccid_usb.c:948:ReadUSB() Waiting data for slot 1
|
||||||
|
[...]
|
||||||
|
02329717 [140486023046912] ccid_usb.c:956:ReadUSB() read failed (1/12): 110 Connection timed out
|
||||||
|
00000028 [140486023046912] ifdhandler.c:1225:IFDHPowerICC() PowerDown failed
|
||||||
|
|
||||||
|
The first PC_to_RDR_IccPowerOff command uses bSeq=4 and is for slot=0.
|
||||||
|
This command works fine.
|
||||||
|
The second PC_to_RDR_IccPowerOff command is for the slot 1 but uses the
|
||||||
|
same bSeq=4. The driver never gets an answer for this command.
|
||||||
|
|
||||||
|
I revert the change and now the bSeq value used by each command is uniq
|
||||||
|
for the reader.
|
||||||
|
|
||||||
|
This reverts commit 5f63ca79cfa3291a943dd14a54fdefa56da3bf28.
|
||||||
|
|
||||||
|
src/ccid.h | 3 ++-
|
||||||
|
src/ccid_serial.c | 3 ++-
|
||||||
|
src/ccid_usb.c | 5 +++--
|
||||||
|
src/commands.c | 18 +++++++++---------
|
||||||
|
4 files changed, 16 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
commit f30bd1fcb1c929b110165eec9cfc29f6b709ef5a
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Tue Nov 2 16:16:26 2021 +0100
|
||||||
|
|
||||||
|
Rename Felica in FeliCa in filenames
|
||||||
|
|
||||||
|
readers/{SONY_Felica_RC-S300_P.txt => SONY_FeliCa_RC-S300_P.txt} | 0
|
||||||
|
readers/{SONY_Felica_RC-S300_S.txt => SONY_FeliCa_RC-S300_S.txt} | 0
|
||||||
|
readers/{SONY_Felica_RC-S660_U.txt => SONY_FeliCa_RC-S660_U.txt} | 0
|
||||||
|
3 files changed, 0 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
commit ab95559647e4382eae699b7823f997aedeb18c70
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Mon Nov 1 13:27:00 2021 +0100
|
||||||
|
|
||||||
|
Fix bClassEnveloppe: field name for 3 Bit4id readers
|
||||||
|
|
||||||
|
The correct name is "bClassEnvelope".
|
||||||
|
This problem has been fixed in CCID parse.c in
|
||||||
|
41119961d8138204b3168e0838272885829815be (May 2013).
|
||||||
|
|
||||||
|
readers/Bit4id_Digital_DNA_Key.txt | 2 +-
|
||||||
|
readers/Bit4id_tokenME_FIPS_v3.txt | 2 +-
|
||||||
|
readers/bit4id_TokenME-EVO.txt | 2 +-
|
||||||
|
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
commit adde6fb74833b3ed47b0579863ca526e81483362
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Oct 31 14:02:31 2021 +0100
|
||||||
|
|
||||||
|
DisconnectUSB(): disconnect all the slots of a multi-slot reader
|
||||||
|
|
||||||
|
When a reader is removed all the slots will become unavailable.
|
||||||
|
|
||||||
|
So to avoid errors logs like:
|
||||||
|
00299802 [139984241678080] ifdhandler.c:1911:IFDHICCPresence() usb:1c34/7124:libudev:0:/dev/bus/usb/001/016 (lun: 10003)
|
||||||
|
00000037 [139984241678080] -> 000004 65 00 00 00 00 03 06 00 00 00
|
||||||
|
00000051 [139984241678080] ccid_usb.c:871:WriteUSB() write failed (1/16): -4 LIBUSB_ERROR_NO_DEVICE
|
||||||
|
we mark all the slots of the same USB device as also disconnected.
|
||||||
|
|
||||||
|
This improves the patch in b0cb37f1aee46d04c31c19273f23967f4ae8601c.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 11 ++++++++++-
|
||||||
|
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit 5d0b4e411b79b68e2166e168230f135ea73f2cb5
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Oct 31 13:56:18 2021 +0100
|
||||||
|
|
||||||
|
Multi_InterruptRead: return IFD_NO_SUCH_DEVICE when exiting
|
||||||
|
|
||||||
|
The value 0 (IFD_SUCCESS) is not a good answer when the driver is
|
||||||
|
stopping or removed.
|
||||||
|
|
||||||
|
The conversion from 0 to IFD_NO_SUCH_DEVICE is no more done in
|
||||||
|
IFDHPolling() as the comments wrongly indicates since
|
||||||
|
commit f83c1ea6806c62d39ba7ba305c92f01658796e47 (Aug 2010) but the code
|
||||||
|
for multislots was not modified at the same time.
|
||||||
|
|
||||||
|
We use IFD_NO_SUCH_DEVICE instead so that pcscd will wait a bit before
|
||||||
|
asking again.
|
||||||
|
|
||||||
|
src/ccid_usb.c | 8 ++++----
|
||||||
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
commit e3baafb89cee3eae9302e454ca25332401b9569c
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sat Oct 30 11:07:20 2021 +0200
|
||||||
|
|
||||||
|
multi-slots: Start the sequence number at 0 for a new slot
|
||||||
|
|
||||||
|
Each slot has its own sequence number (CCID bSeq field). When a new slot
|
||||||
|
is created we start the sequence number at 0 instead of using the value
|
||||||
|
from the previous slot that is copied.
|
||||||
|
|
||||||
|
It is not important but it generates cleaner logs.
|
||||||
|
|
||||||
|
src/ccid_serial.c | 1 +
|
||||||
|
src/ccid_usb.c | 1 +
|
||||||
|
2 files changed, 2 insertions(+)
|
||||||
|
|
||||||
|
commit 5f63ca79cfa3291a943dd14a54fdefa56da3bf28
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Oct 24 18:44:46 2021 +0200
|
||||||
|
|
||||||
|
Each slot has its own sequence number
|
||||||
|
|
||||||
|
src/ccid.h | 3 +--
|
||||||
|
src/ccid_serial.c | 3 +--
|
||||||
|
src/ccid_usb.c | 5 ++---
|
||||||
|
src/commands.c | 18 +++++++++---------
|
||||||
|
4 files changed, 13 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
commit a12a7eb202259b6241ec307fecf8b7d1e365bf7b
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Oct 24 14:24:31 2021 +0200
|
||||||
|
|
||||||
|
Fix incorrect comment
|
||||||
|
|
||||||
|
src/ccid_usb.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit a4eb16ebf922a45cfdd1a916602206378118042a
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Oct 24 14:17:34 2021 +0200
|
||||||
|
|
||||||
|
Fix typo in comment
|
||||||
|
|
||||||
|
src/ccid_usb.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit b801b8ac7be541939d951e2744e42ef0ac07f061
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Oct 27 11:32:43 2021 +0200
|
||||||
|
|
||||||
|
Add ACS ACR1281U
|
||||||
|
|
||||||
|
readers/ACS_ACR1281U.txt | 54 +++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 3 ++-
|
||||||
|
2 files changed, 56 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit 734cea683bdf39dc48816682ba4debcaa0941f47
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Mon Oct 25 09:18:18 2021 +0200
|
||||||
|
|
||||||
|
supported_readers: Use FeliCa instead of Felica on SONY request
|
||||||
|
|
||||||
|
readers/supported_readers.txt | 8 ++++----
|
||||||
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
commit ca395d69a2975def7ef8cbf0e03117f5aa474a4f
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Tue Oct 19 23:23:36 2021 +0200
|
||||||
|
|
||||||
|
t1_transceive: improve code style
|
||||||
|
|
||||||
|
Declare "retries" as an "int" instead of a "unsigned int" so the test
|
||||||
|
"if (retries <= 0)" is true for negative values of retries.
|
||||||
|
|
||||||
|
src/openct/proto-t1.c | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit 831c435d490a1d51d456e04642e18434928c10d8
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Tue Oct 19 22:44:33 2021 +0200
|
||||||
|
|
||||||
|
t1_negotiate_ifsd: improve code style
|
||||||
|
|
||||||
|
Declare "retries" as an "int" instead of a "unsigned int" so the test
|
||||||
|
"if (retries <= 0)" is true for negative values of retries.
|
||||||
|
|
||||||
|
Move the test on retries _before_ sending the T=1 block. In the previous
|
||||||
|
code the block was sent but the result was ignored on the third try.
|
||||||
|
|
||||||
|
Update the check from "if (retries <= 0)" to "if (retries < 0)" so that
|
||||||
|
we really perform 3 tries instead of just 2.
|
||||||
|
|
||||||
|
Thanks to Stas Sergeev for the bug report
|
||||||
|
Fix https://github.com/LudovicRousseau/CCID/issues/91
|
||||||
|
|
||||||
|
src/openct/proto-t1.c | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
commit c7d04806efb9a1a0c1b57a444b2e84d93eeb7558
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Oct 13 21:36:08 2021 +0200
|
||||||
|
|
||||||
|
Add Nitrokey Nitrokey 3
|
||||||
|
|
||||||
|
readers/Nitrokey_Nitrokey_3.txt | 50 +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 3 ++-
|
||||||
|
2 files changed, 52 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit b0cb37f1aee46d04c31c19273f23967f4ae8601c
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Oct 10 17:20:04 2021 +0200
|
||||||
|
|
||||||
|
Avoid logging errors when a reader is removed
|
||||||
|
|
||||||
|
Add support of TAG_IFD_DEVICE_REMOVED
|
||||||
|
This tag has been introduced in pcsc-lite version 1.9.5.
|
||||||
|
|
||||||
|
When the driver receives the tag TAG_IFD_DEVICE_REMOVED it marks the
|
||||||
|
USB device as disconnected and will not try to talk to it any more.
|
||||||
|
|
||||||
|
So when a USB CCID reader is remove we do not have these errors in the
|
||||||
|
logs any more:
|
||||||
|
00000000 [140295925790464] ccid_usb.c:871:WriteUSB() write failed (1/22): -4 LIBUSB_ERROR_NO_DEVICE
|
||||||
|
00000506 [140295934183168] ccid_usb.c:871:WriteUSB() write failed (1/22): -4 LIBUSB_ERROR_NO_DEVICE
|
||||||
|
|
||||||
|
The first error is because IFDHICCPresence() sends the CCID command
|
||||||
|
PC_to_RDR_GetSlotStatus to know if a card is present.
|
||||||
|
|
||||||
|
The second error is because IFDHCloseChannel() sends the CCID command
|
||||||
|
PC_to_RDR_IccPowerOff to power off the card.
|
||||||
|
|
||||||
|
But since the USB device has been removed these 2 CCID commands will
|
||||||
|
fail and log the error.
|
||||||
|
|
||||||
|
Thanks to Jakub Jelen for the bug report
|
||||||
|
" Reader disconnects are noisy in journal/logs #110 "
|
||||||
|
https://github.com/LudovicRousseau/PCSC/issues/110
|
||||||
|
|
||||||
|
See also https://bugzilla.redhat.com/show_bug.cgi?id=2011128
|
||||||
|
|
||||||
|
src/ccid_serial.c | 15 +++++++++++++++
|
||||||
|
src/ccid_serial.h | 2 ++
|
||||||
|
src/ccid_usb.c | 28 ++++++++++++++++++++++++++++
|
||||||
|
src/ccid_usb.h | 1 +
|
||||||
|
src/defs.h | 2 ++
|
||||||
|
src/ifdhandler.c | 29 ++++++++++++++++++++++++++++-
|
||||||
|
6 files changed, 76 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
commit daadc5806c01b1d3b92cd7f7a90387a095578553
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sat Oct 9 18:40:06 2021 +0200
|
||||||
|
|
||||||
|
utils: Use a more special value to indicate a free slot
|
||||||
|
|
||||||
|
The value -1 is not so special as it is also used by pcscd to mark an
|
||||||
|
invalid slot.
|
||||||
|
libccid was happy with Lun = -1 for a reader. This should NOT be the
|
||||||
|
case.
|
||||||
|
|
||||||
|
Now the special value is -42.
|
||||||
|
|
||||||
|
src/utils.c | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
commit 84bd2cc64c259f818da568b812f63e2475cfc09c
|
||||||
|
Merge: cb242a7 92a5302
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau+github@gmail.com>
|
||||||
|
Date: Wed Sep 29 11:38:09 2021 +0200
|
||||||
|
|
||||||
|
Merge pull request #90 from emaxx-google/omnikey-5427-ck
|
||||||
|
|
||||||
|
Allow vendor control commands for Omnikey 5427 CK
|
||||||
|
|
||||||
|
commit 92a5302eb17146574b0d941739264598144f7fcf
|
||||||
|
Author: Maksim Ivanov <emaxx@google.com>
|
||||||
|
Date: Wed Sep 29 07:52:52 2021 +0200
|
||||||
|
|
||||||
|
Allow vendor control commands for Omnikey 5427 CK
|
||||||
|
|
||||||
|
By default, the PC/SC protocol doesn't allow sending commands (APDUs) to
|
||||||
|
a reader that doesn't have a card inserted. There's a legitimate use
|
||||||
|
case (which exactly, isn't relevant here) for supporting this for the
|
||||||
|
Omnikey 5427 CK reader.
|
||||||
|
|
||||||
|
This reader provides a capability for sending APDUs, but only via a
|
||||||
|
vendor control command. By default, vendor control commands are
|
||||||
|
forbidden, and can be enabled for all readers via setting the
|
||||||
|
"ifdDriverOptions" parameter in the Info.plist config to have the bit
|
||||||
|
"1" (DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED). However, enabling this
|
||||||
|
parametere in the config might impose a security risk when using some
|
||||||
|
readers and applications (see
|
||||||
|
https://ludovicrousseau.blogspot.com/2011/10/featureccidesccommand.html).
|
||||||
|
Hence the solution in this commit is to special-case the Omnikey 5427
|
||||||
|
CK reader and allow any application to send control commands. It was
|
||||||
|
confirmed with the reader's vendor that this doesn't impose a security
|
||||||
|
risk here.
|
||||||
|
|
||||||
|
src/ccid.h | 1 +
|
||||||
|
src/ifdhandler.c | 4 ++++
|
||||||
|
2 files changed, 5 insertions(+)
|
||||||
|
|
||||||
|
commit cb242a71fd07dea1a8e4f9efc48684842e7a9387
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Sep 19 10:27:44 2021 +0200
|
||||||
|
|
||||||
|
Hack to hide the ELYCTIS CNT reader reader
|
||||||
|
|
||||||
|
The ELYCTIS reader is a composite reader with 3 iterfaces:
|
||||||
|
one 0x1FFA:0x0002:ELYCTIS CL reader
|
||||||
|
and two 0x04E6:0x5810:ELYCTIS CNT reader
|
||||||
|
|
||||||
|
But the "ELYCTIS CNT reader" is in fact a "Identive CLOUD 2700 R Smart
|
||||||
|
Card Reader" renamed. They both share the same VID/PID.
|
||||||
|
|
||||||
|
Since "ELYCTIS" is before "Identive" in the alphabetical order the
|
||||||
|
VID/PID 0x04E6:0x5810 was now associated with ELYCTIS and not Identive.
|
||||||
|
|
||||||
|
The hack is to rename ELYCTIS into ~ELYCTIS for the 2 contact interfaces
|
||||||
|
so that Identive comes first in the alpahetical order.
|
||||||
|
|
||||||
|
readers/ELYCTIS_CL_reader.txt | 4 ++--
|
||||||
|
readers/supported_readers.txt | 4 +++-
|
||||||
|
2 files changed, 5 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
commit baa0c6e17287ee759bb1d06ca8c505033c62706c
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Sun Sep 19 10:27:20 2021 +0200
|
||||||
|
|
||||||
|
Add ELYCTIS CL reader
|
||||||
|
|
||||||
|
readers/ELYCTIS_CL_reader.txt | 165 ++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
readers/supported_readers.txt | 7 +-
|
||||||
|
2 files changed, 170 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
commit 26ad96076523472e9d0d383d014e7b1ad241fd5b
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Wed Sep 8 11:28:48 2021 +0200
|
||||||
|
|
||||||
|
Fix SafeNet eToken 5110 SC issue (firmware 0.13)
|
||||||
|
|
||||||
|
The SafeNet eToken 5110 SC with firmware 0.13 has the same problem as
|
||||||
|
the token with firmware 0.12.
|
||||||
|
We use the same oslution to fix the problem.
|
||||||
|
|
||||||
|
Thanks again to Vladimir K for the bug report.
|
||||||
|
|
||||||
|
src/ccid.c | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
commit b48e1e697010431b7f03d4ecfe917ceee95e2c64
|
||||||
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
|
Date: Tue Sep 7 14:06:46 2021 +0200
|
||||||
|
|
||||||
|
Fix SafeNet eToken 5110 SC issue
|
||||||
|
|
||||||
|
Some SafeNet eToken 5100 (but not all) have issues when IFSD is negotiated.
|
||||||
|
For some APDU the communication stops and the token returns 0 bytes.
|
||||||
|
|
||||||
|
It is the case with the SafeNet eToken 5110 SC with
|
||||||
|
ATR: 3B D5 18 00 81 31 3A 7D 80 73 C8 21 10 30
|
||||||
|
and PC/SC name "SafeNet eToken 5100 [eToken 5110 SC]"
|
||||||
|
|
||||||
|
Another SafeNet eToken 5100 with
|
||||||
|
ATR: 3B D5 18 00 81 31 FE 7D 80 73 C8 21 10 F4
|
||||||
|
and PC/SC name "SafeNet eToken 5100 [Main Interface]"
|
||||||
|
does NOT have problems with the the IFSD negotiation.
|
||||||
|
|
||||||
|
The 2 devices have (luckily) a different USB CCID descriptor:
|
||||||
|
--- eToken5100_bug 2021-09-07 11:58:30.245354659 +0200
|
||||||
|
+++ eToken5100_ok 2021-09-07 11:58:36.621432673 +0200
|
||||||
|
@@ -2,7 +2,7 @@
|
||||||
|
iManufacturer: SafeNet
|
||||||
|
idProduct: 0x0620
|
||||||
|
iProduct: Token JC
|
||||||
|
- bcdDevice: 0.12 (firmware release?)
|
||||||
|
+ bcdDevice: 1.00 (firmware release?)
|
||||||
|
bLength: 9
|
||||||
|
bDescriptorType: 4
|
||||||
|
bInterfaceNumber: 0
|
||||||
|
@@ -13,7 +13,7 @@
|
||||||
|
bInterfaceSubClass: 0
|
||||||
|
bInterfaceProtocol: 0
|
||||||
|
bulk transfer, optional interrupt-IN (CCID)
|
||||||
|
- iInterface: eToken 5110 SC
|
||||||
|
+ iInterface: Main Interface
|
||||||
|
CCID Class Descriptor
|
||||||
|
bLength: 0x36
|
||||||
|
bDescriptorType: 0x21
|
||||||
|
@@ -26,24 +26,23 @@
|
||||||
|
dwProtocols: 0x0000 0x0003
|
||||||
|
T=0
|
||||||
|
T=1
|
||||||
|
- dwDefaultClock: 4.800 MHz
|
||||||
|
- dwMaximumClock: 4.800 MHz
|
||||||
|
+ dwDefaultClock: 4.000 MHz
|
||||||
|
+ dwMaximumClock: 4.000 MHz
|
||||||
|
bNumClockSupported: 0 (will use whatever is returned)
|
||||||
|
IFD does not support GET CLOCK FREQUENCIES request: LIBUSB_ERROR_PIPE
|
||||||
|
- dwDataRate: 12903 bps
|
||||||
|
- dwMaxDataRate: 12903 bps
|
||||||
|
+ dwDataRate: 10752 bps
|
||||||
|
+ dwMaxDataRate: 10752 bps
|
||||||
|
bNumDataRatesSupported: 0 (will use whatever is returned)
|
||||||
|
IFD does not support GET_DATA_RATES request: LIBUSB_ERROR_PIPE
|
||||||
|
- dwMaxIFSD: 128
|
||||||
|
+ dwMaxIFSD: 252
|
||||||
|
dwSynchProtocols: 0x00000000
|
||||||
|
dwMechanical: 0x00000000
|
||||||
|
No special characteristics
|
||||||
|
- dwFeatures: 0x0001027C
|
||||||
|
+ dwFeatures: 0x0001023C
|
||||||
|
....04 Automatic activation of ICC on inserting
|
||||||
|
....08 Automatic ICC voltage selection
|
||||||
|
....10 Automatic ICC clock frequency change according to parameters
|
||||||
|
....20 Automatic baud rate change according to frequency and Fi, Di params
|
||||||
|
- ....40 Automatic parameters negotiation made by the CCID
|
||||||
|
..02.. NAD value other than 00 accepted (T=1)
|
||||||
|
01.... TPDU level exchange
|
||||||
|
dwMaxCCIDMessageLength: 271 bytes
|
||||||
|
|
||||||
|
This fixes Debian bug #993647
|
||||||
|
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=993647
|
||||||
|
|
||||||
|
src/ccid.c | 7 +++++++
|
||||||
|
src/ccid.h | 1 +
|
||||||
|
2 files changed, 8 insertions(+)
|
||||||
|
|
||||||
|
commit 74642f87f9e1a937e807acd3a7d2ef600b8d151c (tag: 1.4.36)
|
||||||
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
Date: Mon Aug 30 11:14:49 2021 +0200
|
Date: Mon Aug 30 11:14:49 2021 +0200
|
||||||
|
|
||||||
|
@ -94,7 +1038,7 @@ Date: Tue Jul 27 17:05:51 2021 +0200
|
||||||
readers/supported_readers.txt | 3 +-
|
readers/supported_readers.txt | 3 +-
|
||||||
2 files changed, 60 insertions(+), 1 deletion(-)
|
2 files changed, 60 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
commit c0c84311c47fcae11ab34ec7b1f70f9518e37931 (tag: 1.4.35, github/master)
|
commit c0c84311c47fcae11ab34ec7b1f70f9518e37931 (tag: 1.4.35)
|
||||||
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
|
||||||
Date: Sun Jul 25 16:00:35 2021 +0200
|
Date: Sun Jul 25 16:00:35 2021 +0200
|
||||||
|
|
||||||
|
|
16
Makefile.in
16
Makefile.in
|
@ -1,7 +1,7 @@
|
||||||
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
# Makefile.in generated by automake 1.16.5 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -156,13 +156,10 @@ am__define_uniq_tagged_files = \
|
||||||
unique=`for i in $$list; do \
|
unique=`for i in $$list; do \
|
||||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
done | $(am__uniquify_input)`
|
done | $(am__uniquify_input)`
|
||||||
ETAGS = etags
|
|
||||||
CTAGS = ctags
|
|
||||||
CSCOPE = cscope
|
|
||||||
DIST_SUBDIRS = $(SUBDIRS)
|
DIST_SUBDIRS = $(SUBDIRS)
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \
|
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \
|
||||||
COPYING ChangeLog INSTALL NEWS ar-lib compile config.guess \
|
COPYING ChangeLog INSTALL NEWS README.md ar-lib compile \
|
||||||
config.sub depcomp install-sh ltmain.sh missing ylwrap
|
config.guess config.sub install-sh ltmain.sh missing ylwrap
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
distdir = $(PACKAGE)-$(VERSION)
|
distdir = $(PACKAGE)-$(VERSION)
|
||||||
top_distdir = $(distdir)
|
top_distdir = $(distdir)
|
||||||
|
@ -221,6 +218,8 @@ CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
CPP = @CPP@
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CSCOPE = @CSCOPE@
|
||||||
|
CTAGS = @CTAGS@
|
||||||
CYGPATH_W = @CYGPATH_W@
|
CYGPATH_W = @CYGPATH_W@
|
||||||
DEFS = @DEFS@
|
DEFS = @DEFS@
|
||||||
DEPDIR = @DEPDIR@
|
DEPDIR = @DEPDIR@
|
||||||
|
@ -232,6 +231,7 @@ ECHO_C = @ECHO_C@
|
||||||
ECHO_N = @ECHO_N@
|
ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
EGREP = @EGREP@
|
EGREP = @EGREP@
|
||||||
|
ETAGS = @ETAGS@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
FGREP = @FGREP@
|
FGREP = @FGREP@
|
||||||
GREP = @GREP@
|
GREP = @GREP@
|
||||||
|
@ -283,6 +283,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
PTHREAD_CC = @PTHREAD_CC@
|
PTHREAD_CC = @PTHREAD_CC@
|
||||||
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
||||||
|
PTHREAD_CXX = @PTHREAD_CXX@
|
||||||
PTHREAD_LIBS = @PTHREAD_LIBS@
|
PTHREAD_LIBS = @PTHREAD_LIBS@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
SED = @SED@
|
SED = @SED@
|
||||||
|
@ -533,7 +534,6 @@ cscopelist-am: $(am__tagged_files)
|
||||||
distclean-tags:
|
distclean-tags:
|
||||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
|
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
distdir: $(BUILT_SOURCES)
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
|
26
README.md
26
README.md
|
@ -117,6 +117,32 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
History:
|
History:
|
||||||
========
|
========
|
||||||
|
|
||||||
|
1.5.0 - 27 January 2022, Ludovic Rousseau
|
||||||
|
- Add support of
|
||||||
|
- ACS ACR1281U
|
||||||
|
- Circle CCR7125 ICC
|
||||||
|
- Circle CIR125 ICC
|
||||||
|
- Circle CIR125-DOT ICC
|
||||||
|
- Circle CIR215 CL with iProduct 0x2100
|
||||||
|
- Circle CIR315 DI
|
||||||
|
- Circle CIR315 with idProduct: 0x0324
|
||||||
|
- Circle CIR315 with idProduct: 0x7004
|
||||||
|
- Circle CIR415 CL
|
||||||
|
- Circle CIR515 ICC
|
||||||
|
- Circle CIR615 CL
|
||||||
|
- Circle CIR615 CL & 1S
|
||||||
|
- ELYCTIS CL reader
|
||||||
|
- Nitrokey Nitrokey 3
|
||||||
|
- Thales Shield M4 Reader
|
||||||
|
- Add support of simultaneous slot access on multi slots readers
|
||||||
|
- Use FeliCa instead of Felica on SONY request
|
||||||
|
- Fix SafeNet eToken 5110 SC issue
|
||||||
|
- Allow vendor control commands for Omnikey 5427 CK
|
||||||
|
- always compute readTimeout to use a value greater than default 3 seconds
|
||||||
|
- Check the bSeq value when receiving a CCID frame
|
||||||
|
- Avoid logging errors when a reader is removed
|
||||||
|
- Some other minor improvements
|
||||||
|
|
||||||
1.4.36 - 30 August 2021, Ludovic Rousseau
|
1.4.36 - 30 August 2021, Ludovic Rousseau
|
||||||
- Add support of
|
- Add support of
|
||||||
- Lenovo Lenovo Smartcard Wired Keyboard II
|
- Lenovo Lenovo Smartcard Wired Keyboard II
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
|
# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -14,8 +14,8 @@
|
||||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||||
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
|
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],,
|
||||||
[m4_warning([this file was generated for autoconf 2.69.
|
[m4_warning([this file was generated for autoconf 2.71.
|
||||||
You have another version of autoconf. It may work, but is not guaranteed to.
|
You have another version of autoconf. It may work, but is not guaranteed to.
|
||||||
If you have problems, you may need to regenerate the build system entirely.
|
If you have problems, you may need to regenerate the build system entirely.
|
||||||
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
|
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
|
||||||
|
@ -36,20 +36,24 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
|
||||||
# flags that are needed. (The user can also force certain compiler
|
# flags that are needed. (The user can also force certain compiler
|
||||||
# flags/libs to be tested by setting these environment variables.)
|
# flags/libs to be tested by setting these environment variables.)
|
||||||
#
|
#
|
||||||
# Also sets PTHREAD_CC to any special C compiler that is needed for
|
# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is
|
||||||
# multi-threaded programs (defaults to the value of CC otherwise). (This
|
# needed for multi-threaded programs (defaults to the value of CC
|
||||||
# is necessary on AIX to use the special cc_r compiler alias.)
|
# respectively CXX otherwise). (This is necessary on e.g. AIX to use the
|
||||||
|
# special cc_r/CC_r compiler alias.)
|
||||||
#
|
#
|
||||||
# NOTE: You are assumed to not only compile your program with these flags,
|
# NOTE: You are assumed to not only compile your program with these flags,
|
||||||
# but also to link with them as well. For example, you might link with
|
# but also to link with them as well. For example, you might link with
|
||||||
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
|
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
|
||||||
|
# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
|
||||||
#
|
#
|
||||||
# If you are only building threaded programs, you may wish to use these
|
# If you are only building threaded programs, you may wish to use these
|
||||||
# variables in your default LIBS, CFLAGS, and CC:
|
# variables in your default LIBS, CFLAGS, and CC:
|
||||||
#
|
#
|
||||||
# LIBS="$PTHREAD_LIBS $LIBS"
|
# LIBS="$PTHREAD_LIBS $LIBS"
|
||||||
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||||
|
# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
|
||||||
# CC="$PTHREAD_CC"
|
# CC="$PTHREAD_CC"
|
||||||
|
# CXX="$PTHREAD_CXX"
|
||||||
#
|
#
|
||||||
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
|
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
|
||||||
# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
|
# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
|
||||||
|
@ -77,6 +81,7 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
|
||||||
#
|
#
|
||||||
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
|
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
|
||||||
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
|
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
|
||||||
|
# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify it
|
# 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
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
@ -104,7 +109,7 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
|
||||||
# modified version of the Autoconf Macro, you may extend this special
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
# exception to the GPL to apply to your modified version as well.
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
#serial 24
|
#serial 31
|
||||||
|
|
||||||
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
|
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
|
||||||
AC_DEFUN([AX_PTHREAD], [
|
AC_DEFUN([AX_PTHREAD], [
|
||||||
|
@ -126,6 +131,7 @@ if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
|
||||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||||
ax_pthread_save_LIBS="$LIBS"
|
ax_pthread_save_LIBS="$LIBS"
|
||||||
AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
|
AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
|
||||||
|
AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"])
|
||||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||||
LIBS="$PTHREAD_LIBS $LIBS"
|
LIBS="$PTHREAD_LIBS $LIBS"
|
||||||
AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
|
AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
|
||||||
|
@ -145,10 +151,12 @@ fi
|
||||||
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
|
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
|
||||||
# libraries is broken (non-POSIX).
|
# libraries is broken (non-POSIX).
|
||||||
|
|
||||||
# Create a list of thread flags to try. Items starting with a "-" are
|
# Create a list of thread flags to try. Items with a "," contain both
|
||||||
# C compiler flags, and other items are library names, except for "none"
|
# C compiler flags (before ",") and linker flags (after ","). Other items
|
||||||
# which indicates that we try without any flags at all, and "pthread-config"
|
# starting with a "-" are C compiler flags, and remaining items are
|
||||||
# which is a program returning the flags for the Pth emulation library.
|
# library names, except for "none" which indicates that we try without
|
||||||
|
# any flags at all, and "pthread-config" which is a program returning
|
||||||
|
# the flags for the Pth emulation library.
|
||||||
|
|
||||||
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
|
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
|
||||||
|
|
||||||
|
@ -216,14 +224,47 @@ case $host_os in
|
||||||
# that too in a future libc.) So we'll check first for the
|
# that too in a future libc.) So we'll check first for the
|
||||||
# standard Solaris way of linking pthreads (-mt -lpthread).
|
# standard Solaris way of linking pthreads (-mt -lpthread).
|
||||||
|
|
||||||
ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
|
ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# Are we compiling with Clang?
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether $CC is Clang],
|
||||||
|
[ax_cv_PTHREAD_CLANG],
|
||||||
|
[ax_cv_PTHREAD_CLANG=no
|
||||||
|
# Note that Autoconf sets GCC=yes for Clang as well as GCC
|
||||||
|
if test "x$GCC" = "xyes"; then
|
||||||
|
AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
|
||||||
|
[/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
|
||||||
|
# if defined(__clang__) && defined(__llvm__)
|
||||||
|
AX_PTHREAD_CC_IS_CLANG
|
||||||
|
# endif
|
||||||
|
],
|
||||||
|
[ax_cv_PTHREAD_CLANG=yes])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
|
||||||
|
|
||||||
|
|
||||||
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
|
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
|
||||||
|
|
||||||
|
# Note that for GCC and Clang -pthread generally implies -lpthread,
|
||||||
|
# except when -nostdlib is passed.
|
||||||
|
# This is problematic using libtool to build C++ shared libraries with pthread:
|
||||||
|
# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
|
||||||
|
# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
|
||||||
|
# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
|
||||||
|
# To solve this, first try -pthread together with -lpthread for GCC
|
||||||
|
|
||||||
AS_IF([test "x$GCC" = "xyes"],
|
AS_IF([test "x$GCC" = "xyes"],
|
||||||
[ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
|
[ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
|
||||||
|
|
||||||
|
# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
|
||||||
|
|
||||||
|
AS_IF([test "x$ax_pthread_clang" = "xyes"],
|
||||||
|
[ax_pthread_flags="-pthread,-lpthread -pthread"])
|
||||||
|
|
||||||
|
|
||||||
# The presence of a feature test macro requesting re-entrant function
|
# The presence of a feature test macro requesting re-entrant function
|
||||||
# definitions is, on some systems, a strong hint that pthreads support is
|
# definitions is, on some systems, a strong hint that pthreads support is
|
||||||
|
@ -246,101 +287,6 @@ AS_IF([test "x$ax_pthread_check_macro" = "x--"],
|
||||||
[ax_pthread_check_cond=0],
|
[ax_pthread_check_cond=0],
|
||||||
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
|
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
|
||||||
|
|
||||||
# Are we compiling with Clang?
|
|
||||||
|
|
||||||
AC_CACHE_CHECK([whether $CC is Clang],
|
|
||||||
[ax_cv_PTHREAD_CLANG],
|
|
||||||
[ax_cv_PTHREAD_CLANG=no
|
|
||||||
# Note that Autoconf sets GCC=yes for Clang as well as GCC
|
|
||||||
if test "x$GCC" = "xyes"; then
|
|
||||||
AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
|
|
||||||
[/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
|
|
||||||
# if defined(__clang__) && defined(__llvm__)
|
|
||||||
AX_PTHREAD_CC_IS_CLANG
|
|
||||||
# endif
|
|
||||||
],
|
|
||||||
[ax_cv_PTHREAD_CLANG=yes])
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
|
|
||||||
|
|
||||||
ax_pthread_clang_warning=no
|
|
||||||
|
|
||||||
# Clang needs special handling, because older versions handle the -pthread
|
|
||||||
# option in a rather... idiosyncratic way
|
|
||||||
|
|
||||||
if test "x$ax_pthread_clang" = "xyes"; then
|
|
||||||
|
|
||||||
# Clang takes -pthread; it has never supported any other flag
|
|
||||||
|
|
||||||
# (Note 1: This will need to be revisited if a system that Clang
|
|
||||||
# supports has POSIX threads in a separate library. This tends not
|
|
||||||
# to be the way of modern systems, but it's conceivable.)
|
|
||||||
|
|
||||||
# (Note 2: On some systems, notably Darwin, -pthread is not needed
|
|
||||||
# to get POSIX threads support; the API is always present and
|
|
||||||
# active. We could reasonably leave PTHREAD_CFLAGS empty. But
|
|
||||||
# -pthread does define _REENTRANT, and while the Darwin headers
|
|
||||||
# ignore this macro, third-party headers might not.)
|
|
||||||
|
|
||||||
PTHREAD_CFLAGS="-pthread"
|
|
||||||
PTHREAD_LIBS=
|
|
||||||
|
|
||||||
ax_pthread_ok=yes
|
|
||||||
|
|
||||||
# However, older versions of Clang make a point of warning the user
|
|
||||||
# that, in an invocation where only linking and no compilation is
|
|
||||||
# taking place, the -pthread option has no effect ("argument unused
|
|
||||||
# during compilation"). They expect -pthread to be passed in only
|
|
||||||
# when source code is being compiled.
|
|
||||||
#
|
|
||||||
# Problem is, this is at odds with the way Automake and most other
|
|
||||||
# C build frameworks function, which is that the same flags used in
|
|
||||||
# compilation (CFLAGS) are also used in linking. Many systems
|
|
||||||
# supported by AX_PTHREAD require exactly this for POSIX threads
|
|
||||||
# support, and in fact it is often not straightforward to specify a
|
|
||||||
# flag that is used only in the compilation phase and not in
|
|
||||||
# linking. Such a scenario is extremely rare in practice.
|
|
||||||
#
|
|
||||||
# Even though use of the -pthread flag in linking would only print
|
|
||||||
# a warning, this can be a nuisance for well-run software projects
|
|
||||||
# that build with -Werror. So if the active version of Clang has
|
|
||||||
# this misfeature, we search for an option to squash it.
|
|
||||||
|
|
||||||
AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
|
|
||||||
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
|
|
||||||
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
|
|
||||||
# Create an alternate version of $ac_link that compiles and
|
|
||||||
# links in two steps (.c -> .o, .o -> exe) instead of one
|
|
||||||
# (.c -> exe), because the warning occurs only in the second
|
|
||||||
# step
|
|
||||||
ax_pthread_save_ac_link="$ac_link"
|
|
||||||
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
|
|
||||||
ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
|
|
||||||
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
|
|
||||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
|
||||||
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
|
|
||||||
AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
|
|
||||||
CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
|
|
||||||
ac_link="$ax_pthread_save_ac_link"
|
|
||||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
|
|
||||||
[ac_link="$ax_pthread_2step_ac_link"
|
|
||||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
|
|
||||||
[break])
|
|
||||||
])
|
|
||||||
done
|
|
||||||
ac_link="$ax_pthread_save_ac_link"
|
|
||||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
|
||||||
AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
|
|
||||||
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
|
|
||||||
])
|
|
||||||
|
|
||||||
case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
|
|
||||||
no | unknown) ;;
|
|
||||||
*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
fi # $ax_pthread_clang = yes
|
|
||||||
|
|
||||||
if test "x$ax_pthread_ok" = "xno"; then
|
if test "x$ax_pthread_ok" = "xno"; then
|
||||||
for ax_pthread_try_flag in $ax_pthread_flags; do
|
for ax_pthread_try_flag in $ax_pthread_flags; do
|
||||||
|
@ -350,10 +296,10 @@ for ax_pthread_try_flag in $ax_pthread_flags; do
|
||||||
AC_MSG_CHECKING([whether pthreads work without any flags])
|
AC_MSG_CHECKING([whether pthreads work without any flags])
|
||||||
;;
|
;;
|
||||||
|
|
||||||
-mt,pthread)
|
*,*)
|
||||||
AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
|
PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
|
||||||
PTHREAD_CFLAGS="-mt"
|
PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
|
||||||
PTHREAD_LIBS="-lpthread"
|
AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
|
||||||
;;
|
;;
|
||||||
|
|
||||||
-*)
|
-*)
|
||||||
|
@ -393,7 +339,13 @@ for ax_pthread_try_flag in $ax_pthread_flags; do
|
||||||
# if $ax_pthread_check_cond
|
# if $ax_pthread_check_cond
|
||||||
# error "$ax_pthread_check_macro must be defined"
|
# error "$ax_pthread_check_macro must be defined"
|
||||||
# endif
|
# endif
|
||||||
static void routine(void *a) { a = 0; }
|
static void *some_global = NULL;
|
||||||
|
static void routine(void *a)
|
||||||
|
{
|
||||||
|
/* To avoid any unused-parameter or
|
||||||
|
unused-but-set-parameter warning. */
|
||||||
|
some_global = a;
|
||||||
|
}
|
||||||
static void *start_routine(void *a) { return a; }],
|
static void *start_routine(void *a) { return a; }],
|
||||||
[pthread_t th; pthread_attr_t attr;
|
[pthread_t th; pthread_attr_t attr;
|
||||||
pthread_create(&th, 0, start_routine, 0);
|
pthread_create(&th, 0, start_routine, 0);
|
||||||
|
@ -415,6 +367,80 @@ for ax_pthread_try_flag in $ax_pthread_flags; do
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Clang needs special handling, because older versions handle the -pthread
|
||||||
|
# option in a rather... idiosyncratic way
|
||||||
|
|
||||||
|
if test "x$ax_pthread_clang" = "xyes"; then
|
||||||
|
|
||||||
|
# Clang takes -pthread; it has never supported any other flag
|
||||||
|
|
||||||
|
# (Note 1: This will need to be revisited if a system that Clang
|
||||||
|
# supports has POSIX threads in a separate library. This tends not
|
||||||
|
# to be the way of modern systems, but it's conceivable.)
|
||||||
|
|
||||||
|
# (Note 2: On some systems, notably Darwin, -pthread is not needed
|
||||||
|
# to get POSIX threads support; the API is always present and
|
||||||
|
# active. We could reasonably leave PTHREAD_CFLAGS empty. But
|
||||||
|
# -pthread does define _REENTRANT, and while the Darwin headers
|
||||||
|
# ignore this macro, third-party headers might not.)
|
||||||
|
|
||||||
|
# However, older versions of Clang make a point of warning the user
|
||||||
|
# that, in an invocation where only linking and no compilation is
|
||||||
|
# taking place, the -pthread option has no effect ("argument unused
|
||||||
|
# during compilation"). They expect -pthread to be passed in only
|
||||||
|
# when source code is being compiled.
|
||||||
|
#
|
||||||
|
# Problem is, this is at odds with the way Automake and most other
|
||||||
|
# C build frameworks function, which is that the same flags used in
|
||||||
|
# compilation (CFLAGS) are also used in linking. Many systems
|
||||||
|
# supported by AX_PTHREAD require exactly this for POSIX threads
|
||||||
|
# support, and in fact it is often not straightforward to specify a
|
||||||
|
# flag that is used only in the compilation phase and not in
|
||||||
|
# linking. Such a scenario is extremely rare in practice.
|
||||||
|
#
|
||||||
|
# Even though use of the -pthread flag in linking would only print
|
||||||
|
# a warning, this can be a nuisance for well-run software projects
|
||||||
|
# that build with -Werror. So if the active version of Clang has
|
||||||
|
# this misfeature, we search for an option to squash it.
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
|
||||||
|
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
|
||||||
|
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
|
||||||
|
# Create an alternate version of $ac_link that compiles and
|
||||||
|
# links in two steps (.c -> .o, .o -> exe) instead of one
|
||||||
|
# (.c -> exe), because the warning occurs only in the second
|
||||||
|
# step
|
||||||
|
ax_pthread_save_ac_link="$ac_link"
|
||||||
|
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
|
||||||
|
ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"`
|
||||||
|
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
|
||||||
|
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||||
|
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
|
||||||
|
AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
|
||||||
|
CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
|
||||||
|
ac_link="$ax_pthread_save_ac_link"
|
||||||
|
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
|
||||||
|
[ac_link="$ax_pthread_2step_ac_link"
|
||||||
|
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
|
||||||
|
[break])
|
||||||
|
])
|
||||||
|
done
|
||||||
|
ac_link="$ax_pthread_save_ac_link"
|
||||||
|
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||||
|
AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
|
||||||
|
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
|
||||||
|
])
|
||||||
|
|
||||||
|
case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
|
||||||
|
no | unknown) ;;
|
||||||
|
*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
fi # $ax_pthread_clang = yes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Various other checks:
|
# Various other checks:
|
||||||
if test "x$ax_pthread_ok" = "xyes"; then
|
if test "x$ax_pthread_ok" = "xyes"; then
|
||||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||||
|
@ -460,7 +486,8 @@ if test "x$ax_pthread_ok" = "xyes"; then
|
||||||
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
|
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
|
||||||
[ax_cv_PTHREAD_PRIO_INHERIT],
|
[ax_cv_PTHREAD_PRIO_INHERIT],
|
||||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
|
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
|
||||||
[[int i = PTHREAD_PRIO_INHERIT;]])],
|
[[int i = PTHREAD_PRIO_INHERIT;
|
||||||
|
return i;]])],
|
||||||
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
|
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
|
||||||
[ax_cv_PTHREAD_PRIO_INHERIT=no])
|
[ax_cv_PTHREAD_PRIO_INHERIT=no])
|
||||||
])
|
])
|
||||||
|
@ -482,18 +509,28 @@ if test "x$ax_pthread_ok" = "xyes"; then
|
||||||
[#handle absolute path differently from PATH based program lookup
|
[#handle absolute path differently from PATH based program lookup
|
||||||
AS_CASE(["x$CC"],
|
AS_CASE(["x$CC"],
|
||||||
[x/*],
|
[x/*],
|
||||||
[AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
|
[
|
||||||
[AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
|
AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])
|
||||||
|
AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])])
|
||||||
|
],
|
||||||
|
[
|
||||||
|
AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])
|
||||||
|
AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
])
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
|
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
|
||||||
|
test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
|
||||||
|
|
||||||
AC_SUBST([PTHREAD_LIBS])
|
AC_SUBST([PTHREAD_LIBS])
|
||||||
AC_SUBST([PTHREAD_CFLAGS])
|
AC_SUBST([PTHREAD_CFLAGS])
|
||||||
AC_SUBST([PTHREAD_CC])
|
AC_SUBST([PTHREAD_CC])
|
||||||
|
AC_SUBST([PTHREAD_CXX])
|
||||||
|
|
||||||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
||||||
if test "x$ax_pthread_ok" = "xyes"; then
|
if test "x$ax_pthread_ok" = "xyes"; then
|
||||||
|
@ -782,7 +819,7 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
|
||||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
||||||
])dnl PKG_CHECK_VAR
|
])dnl PKG_CHECK_VAR
|
||||||
|
|
||||||
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2002-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -797,7 +834,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||||
[am__api_version='1.16'
|
[am__api_version='1.16'
|
||||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||||
dnl require some minimum version. Point them to the right macro.
|
dnl require some minimum version. Point them to the right macro.
|
||||||
m4_if([$1], [1.16.3], [],
|
m4_if([$1], [1.16.5], [],
|
||||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -813,12 +850,12 @@ m4_define([_AM_AUTOCONF_VERSION], [])
|
||||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||||
[AM_AUTOMAKE_VERSION([1.16.3])dnl
|
[AM_AUTOMAKE_VERSION([1.16.5])dnl
|
||||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||||
|
|
||||||
# Copyright (C) 2011-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2011-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -880,7 +917,7 @@ AC_SUBST([AR])dnl
|
||||||
|
|
||||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -932,7 +969,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||||
|
|
||||||
# AM_CONDITIONAL -*- Autoconf -*-
|
# AM_CONDITIONAL -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1997-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -963,7 +1000,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||||
Usually this means the macro was only invoked conditionally.]])
|
Usually this means the macro was only invoked conditionally.]])
|
||||||
fi])])
|
fi])])
|
||||||
|
|
||||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1154,7 +1191,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
|
||||||
|
|
||||||
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1222,7 +1259,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||||
|
|
||||||
# Do all the work for Automake. -*- Autoconf -*-
|
# Do all the work for Automake. -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1250,6 +1287,10 @@ m4_defn([AC_PROG_CC])
|
||||||
# release and drop the old call support.
|
# release and drop the old call support.
|
||||||
AC_DEFUN([AM_INIT_AUTOMAKE],
|
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||||
[AC_PREREQ([2.65])dnl
|
[AC_PREREQ([2.65])dnl
|
||||||
|
m4_ifdef([_$0_ALREADY_INIT],
|
||||||
|
[m4_fatal([$0 expanded multiple times
|
||||||
|
]m4_defn([_$0_ALREADY_INIT]))],
|
||||||
|
[m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl
|
||||||
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
||||||
dnl the ones we care about.
|
dnl the ones we care about.
|
||||||
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
||||||
|
@ -1286,7 +1327,7 @@ m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||||
[_AM_SET_OPTIONS([$1])dnl
|
[_AM_SET_OPTIONS([$1])dnl
|
||||||
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
|
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
|
||||||
m4_if(
|
m4_if(
|
||||||
m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
|
m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]),
|
||||||
[ok:ok],,
|
[ok:ok],,
|
||||||
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
|
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
|
||||||
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
||||||
|
@ -1338,6 +1379,20 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
|
||||||
[m4_define([AC_PROG_OBJCXX],
|
[m4_define([AC_PROG_OBJCXX],
|
||||||
m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
|
m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
|
||||||
])
|
])
|
||||||
|
# Variables for tags utilities; see am/tags.am
|
||||||
|
if test -z "$CTAGS"; then
|
||||||
|
CTAGS=ctags
|
||||||
|
fi
|
||||||
|
AC_SUBST([CTAGS])
|
||||||
|
if test -z "$ETAGS"; then
|
||||||
|
ETAGS=etags
|
||||||
|
fi
|
||||||
|
AC_SUBST([ETAGS])
|
||||||
|
if test -z "$CSCOPE"; then
|
||||||
|
CSCOPE=cscope
|
||||||
|
fi
|
||||||
|
AC_SUBST([CSCOPE])
|
||||||
|
|
||||||
AC_REQUIRE([AM_SILENT_RULES])dnl
|
AC_REQUIRE([AM_SILENT_RULES])dnl
|
||||||
dnl The testsuite driver may need to know about EXEEXT, so add the
|
dnl The testsuite driver may need to know about EXEEXT, so add the
|
||||||
dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
|
dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
|
||||||
|
@ -1419,7 +1474,7 @@ for _am_header in $config_headers :; do
|
||||||
done
|
done
|
||||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||||
|
|
||||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1440,7 +1495,7 @@ if test x"${install_sh+set}" != xset; then
|
||||||
fi
|
fi
|
||||||
AC_SUBST([install_sh])])
|
AC_SUBST([install_sh])])
|
||||||
|
|
||||||
# Copyright (C) 2003-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2003-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1459,7 +1514,7 @@ fi
|
||||||
rmdir .tst 2>/dev/null
|
rmdir .tst 2>/dev/null
|
||||||
AC_SUBST([am__leading_dot])])
|
AC_SUBST([am__leading_dot])])
|
||||||
|
|
||||||
# Copyright (C) 1998-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1998-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1480,7 +1535,7 @@ fi])
|
||||||
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
|
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
|
||||||
# From Jim Meyering
|
# From Jim Meyering
|
||||||
|
|
||||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1515,7 +1570,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
|
||||||
|
|
||||||
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1558,7 +1613,7 @@ AC_SUBST([am__quote])])
|
||||||
|
|
||||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1997-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1592,7 +1647,7 @@ fi
|
||||||
|
|
||||||
# Helper functions for option handling. -*- Autoconf -*-
|
# Helper functions for option handling. -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1621,7 +1676,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
|
||||||
AC_DEFUN([_AM_IF_OPTION],
|
AC_DEFUN([_AM_IF_OPTION],
|
||||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||||
|
|
||||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1668,7 +1723,7 @@ AC_LANG_POP([C])])
|
||||||
# For backward compatibility.
|
# For backward compatibility.
|
||||||
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
|
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
|
||||||
|
|
||||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1687,7 +1742,7 @@ AC_DEFUN([AM_RUN_LOG],
|
||||||
|
|
||||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1768,7 +1823,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||||
rm -f conftest.file
|
rm -f conftest.file
|
||||||
])
|
])
|
||||||
|
|
||||||
# Copyright (C) 2009-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2009-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1828,7 +1883,7 @@ AC_SUBST([AM_BACKSLASH])dnl
|
||||||
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
|
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
|
||||||
])
|
])
|
||||||
|
|
||||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1856,7 +1911,7 @@ fi
|
||||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||||
|
|
||||||
# Copyright (C) 2006-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2006-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1875,7 +1930,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||||
|
|
||||||
# Check how to create a tarball. -*- Autoconf -*-
|
# Check how to create a tarball. -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 2004-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2004-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
|
2
ar-lib
2
ar-lib
|
@ -4,7 +4,7 @@
|
||||||
me=ar-lib
|
me=ar-lib
|
||||||
scriptversion=2019-07-04.01; # UTC
|
scriptversion=2019-07-04.01; # UTC
|
||||||
|
|
||||||
# Copyright (C) 2010-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2010-2021 Free Software Foundation, Inc.
|
||||||
# Written by Peter Rosin <peda@lysator.liu.se>.
|
# Written by Peter Rosin <peda@lysator.liu.se>.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
|
2
compile
2
compile
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
scriptversion=2018-03-07.03; # UTC
|
scriptversion=2018-03-07.03; # UTC
|
||||||
|
|
||||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -27,9 +27,6 @@
|
||||||
/* Define to 1 if you have the `memcpy' function. */
|
/* Define to 1 if you have the `memcpy' function. */
|
||||||
#undef HAVE_MEMCPY
|
#undef HAVE_MEMCPY
|
||||||
|
|
||||||
/* Define to 1 if you have the <memory.h> header file. */
|
|
||||||
#undef HAVE_MEMORY_H
|
|
||||||
|
|
||||||
/* Define if you have POSIX threads libraries and header files. */
|
/* Define if you have POSIX threads libraries and header files. */
|
||||||
#undef HAVE_PTHREAD
|
#undef HAVE_PTHREAD
|
||||||
|
|
||||||
|
@ -118,7 +115,9 @@
|
||||||
your system. */
|
your system. */
|
||||||
#undef PTHREAD_CREATE_JOINABLE
|
#undef PTHREAD_CREATE_JOINABLE
|
||||||
|
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
/* Define to 1 if all of the C90 standard headers exist (not just the ones
|
||||||
|
required in a freestanding environment). This macro is provided for
|
||||||
|
backward compatibility; new code need not use it. */
|
||||||
#undef STDC_HEADERS
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
/* composite device are seen as multi-slots */
|
/* composite device are seen as multi-slots */
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# Require autoconf 2.61
|
# Require autoconf 2.61
|
||||||
AC_PREREQ([2.69])
|
AC_PREREQ([2.69])
|
||||||
|
|
||||||
AC_INIT([ccid],[1.4.36])
|
AC_INIT([ccid],[1.5.0])
|
||||||
AC_CONFIG_SRCDIR(src/ifdhandler.c)
|
AC_CONFIG_SRCDIR(src/ifdhandler.c)
|
||||||
AC_CONFIG_AUX_DIR([.])
|
AC_CONFIG_AUX_DIR([.])
|
||||||
AM_INIT_AUTOMAKE(1.8 dist-bzip2 no-dist-gzip subdir-objects foreign)
|
AM_INIT_AUTOMAKE(1.8 dist-bzip2 no-dist-gzip subdir-objects foreign)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
# Makefile.in generated by automake 1.16.5 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -178,8 +178,6 @@ am__define_uniq_tagged_files = \
|
||||||
unique=`for i in $$list; do \
|
unique=`for i in $$list; do \
|
||||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
done | $(am__uniquify_input)`
|
done | $(am__uniquify_input)`
|
||||||
ETAGS = etags
|
|
||||||
CTAGS = ctags
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
ACLOCAL = @ACLOCAL@
|
ACLOCAL = @ACLOCAL@
|
||||||
|
@ -196,6 +194,8 @@ CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
CPP = @CPP@
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CSCOPE = @CSCOPE@
|
||||||
|
CTAGS = @CTAGS@
|
||||||
CYGPATH_W = @CYGPATH_W@
|
CYGPATH_W = @CYGPATH_W@
|
||||||
DEFS = @DEFS@
|
DEFS = @DEFS@
|
||||||
DEPDIR = @DEPDIR@
|
DEPDIR = @DEPDIR@
|
||||||
|
@ -207,6 +207,7 @@ ECHO_C = @ECHO_C@
|
||||||
ECHO_N = @ECHO_N@
|
ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
EGREP = @EGREP@
|
EGREP = @EGREP@
|
||||||
|
ETAGS = @ETAGS@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
FGREP = @FGREP@
|
FGREP = @FGREP@
|
||||||
GREP = @GREP@
|
GREP = @GREP@
|
||||||
|
@ -256,6 +257,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
PTHREAD_CC = @PTHREAD_CC@
|
PTHREAD_CC = @PTHREAD_CC@
|
||||||
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
||||||
|
PTHREAD_CXX = @PTHREAD_CXX@
|
||||||
PTHREAD_LIBS = @PTHREAD_LIBS@
|
PTHREAD_LIBS = @PTHREAD_LIBS@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
SED = @SED@
|
SED = @SED@
|
||||||
|
@ -485,7 +487,6 @@ cscopelist-am: $(am__tagged_files)
|
||||||
|
|
||||||
distclean-tags:
|
distclean-tags:
|
||||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
distdir: $(BUILT_SOURCES)
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
# Makefile.in generated by automake 1.16.5 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -152,8 +152,6 @@ am__define_uniq_tagged_files = \
|
||||||
unique=`for i in $$list; do \
|
unique=`for i in $$list; do \
|
||||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
done | $(am__uniquify_input)`
|
done | $(am__uniquify_input)`
|
||||||
ETAGS = etags
|
|
||||||
CTAGS = ctags
|
|
||||||
DIST_SUBDIRS = RSA_SecurID Kobil_mIDentity_switch
|
DIST_SUBDIRS = RSA_SecurID Kobil_mIDentity_switch
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in
|
am__DIST_COMMON = $(srcdir)/Makefile.in
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
@ -196,6 +194,8 @@ CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
CPP = @CPP@
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CSCOPE = @CSCOPE@
|
||||||
|
CTAGS = @CTAGS@
|
||||||
CYGPATH_W = @CYGPATH_W@
|
CYGPATH_W = @CYGPATH_W@
|
||||||
DEFS = @DEFS@
|
DEFS = @DEFS@
|
||||||
DEPDIR = @DEPDIR@
|
DEPDIR = @DEPDIR@
|
||||||
|
@ -207,6 +207,7 @@ ECHO_C = @ECHO_C@
|
||||||
ECHO_N = @ECHO_N@
|
ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
EGREP = @EGREP@
|
EGREP = @EGREP@
|
||||||
|
ETAGS = @ETAGS@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
FGREP = @FGREP@
|
FGREP = @FGREP@
|
||||||
GREP = @GREP@
|
GREP = @GREP@
|
||||||
|
@ -256,6 +257,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
PTHREAD_CC = @PTHREAD_CC@
|
PTHREAD_CC = @PTHREAD_CC@
|
||||||
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
||||||
|
PTHREAD_CXX = @PTHREAD_CXX@
|
||||||
PTHREAD_LIBS = @PTHREAD_LIBS@
|
PTHREAD_LIBS = @PTHREAD_LIBS@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
SED = @SED@
|
SED = @SED@
|
||||||
|
@ -462,7 +464,6 @@ cscopelist-am: $(am__tagged_files)
|
||||||
|
|
||||||
distclean-tags:
|
distclean-tags:
|
||||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
distdir: $(BUILT_SOURCES)
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
# Makefile.in generated by automake 1.16.5 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -176,8 +176,6 @@ am__define_uniq_tagged_files = \
|
||||||
unique=`for i in $$list; do \
|
unique=`for i in $$list; do \
|
||||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
done | $(am__uniquify_input)`
|
done | $(am__uniquify_input)`
|
||||||
ETAGS = etags
|
|
||||||
CTAGS = ctags
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
ACLOCAL = @ACLOCAL@
|
ACLOCAL = @ACLOCAL@
|
||||||
|
@ -194,6 +192,8 @@ CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
CPP = @CPP@
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CSCOPE = @CSCOPE@
|
||||||
|
CTAGS = @CTAGS@
|
||||||
CYGPATH_W = @CYGPATH_W@
|
CYGPATH_W = @CYGPATH_W@
|
||||||
DEFS = @DEFS@
|
DEFS = @DEFS@
|
||||||
DEPDIR = @DEPDIR@
|
DEPDIR = @DEPDIR@
|
||||||
|
@ -205,6 +205,7 @@ ECHO_C = @ECHO_C@
|
||||||
ECHO_N = @ECHO_N@
|
ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
EGREP = @EGREP@
|
EGREP = @EGREP@
|
||||||
|
ETAGS = @ETAGS@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
FGREP = @FGREP@
|
FGREP = @FGREP@
|
||||||
GREP = @GREP@
|
GREP = @GREP@
|
||||||
|
@ -254,6 +255,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
PTHREAD_CC = @PTHREAD_CC@
|
PTHREAD_CC = @PTHREAD_CC@
|
||||||
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
||||||
|
PTHREAD_CXX = @PTHREAD_CXX@
|
||||||
PTHREAD_LIBS = @PTHREAD_LIBS@
|
PTHREAD_LIBS = @PTHREAD_LIBS@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
SED = @SED@
|
SED = @SED@
|
||||||
|
@ -482,7 +484,6 @@ cscopelist-am: $(am__tagged_files)
|
||||||
|
|
||||||
distclean-tags:
|
distclean-tags:
|
||||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
distdir: $(BUILT_SOURCES)
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
|
2
depcomp
2
depcomp
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
scriptversion=2018-03-07.03; # UTC
|
scriptversion=2018-03-07.03; # UTC
|
||||||
|
|
||||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
# Makefile.in generated by automake 1.16.5 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -178,8 +178,6 @@ am__define_uniq_tagged_files = \
|
||||||
unique=`for i in $$list; do \
|
unique=`for i in $$list; do \
|
||||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
done | $(am__uniquify_input)`
|
done | $(am__uniquify_input)`
|
||||||
ETAGS = etags
|
|
||||||
CTAGS = ctags
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
ACLOCAL = @ACLOCAL@
|
ACLOCAL = @ACLOCAL@
|
||||||
|
@ -196,6 +194,8 @@ CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
CPP = @CPP@
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CSCOPE = @CSCOPE@
|
||||||
|
CTAGS = @CTAGS@
|
||||||
CYGPATH_W = @CYGPATH_W@
|
CYGPATH_W = @CYGPATH_W@
|
||||||
DEFS = @DEFS@
|
DEFS = @DEFS@
|
||||||
DEPDIR = @DEPDIR@
|
DEPDIR = @DEPDIR@
|
||||||
|
@ -207,6 +207,7 @@ ECHO_C = @ECHO_C@
|
||||||
ECHO_N = @ECHO_N@
|
ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
EGREP = @EGREP@
|
EGREP = @EGREP@
|
||||||
|
ETAGS = @ETAGS@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
FGREP = @FGREP@
|
FGREP = @FGREP@
|
||||||
GREP = @GREP@
|
GREP = @GREP@
|
||||||
|
@ -256,6 +257,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
PTHREAD_CC = @PTHREAD_CC@
|
PTHREAD_CC = @PTHREAD_CC@
|
||||||
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
||||||
|
PTHREAD_CXX = @PTHREAD_CXX@
|
||||||
PTHREAD_LIBS = @PTHREAD_LIBS@
|
PTHREAD_LIBS = @PTHREAD_LIBS@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
SED = @SED@
|
SED = @SED@
|
||||||
|
@ -498,7 +500,6 @@ cscopelist-am: $(am__tagged_files)
|
||||||
|
|
||||||
distclean-tags:
|
distclean-tags:
|
||||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
distdir: $(BUILT_SOURCES)
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
|
2
missing
2
missing
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
scriptversion=2018-03-07.03; # UTC
|
scriptversion=2018-03-07.03; # UTC
|
||||||
|
|
||||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
# Makefile.in generated by automake 1.16.5 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -136,6 +136,8 @@ CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
CPP = @CPP@
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CSCOPE = @CSCOPE@
|
||||||
|
CTAGS = @CTAGS@
|
||||||
CYGPATH_W = @CYGPATH_W@
|
CYGPATH_W = @CYGPATH_W@
|
||||||
DEFS = @DEFS@
|
DEFS = @DEFS@
|
||||||
DEPDIR = @DEPDIR@
|
DEPDIR = @DEPDIR@
|
||||||
|
@ -147,6 +149,7 @@ ECHO_C = @ECHO_C@
|
||||||
ECHO_N = @ECHO_N@
|
ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
EGREP = @EGREP@
|
EGREP = @EGREP@
|
||||||
|
ETAGS = @ETAGS@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
FGREP = @FGREP@
|
FGREP = @FGREP@
|
||||||
GREP = @GREP@
|
GREP = @GREP@
|
||||||
|
@ -196,6 +199,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
PTHREAD_CC = @PTHREAD_CC@
|
PTHREAD_CC = @PTHREAD_CC@
|
||||||
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
||||||
|
PTHREAD_CXX = @PTHREAD_CXX@
|
||||||
PTHREAD_LIBS = @PTHREAD_LIBS@
|
PTHREAD_LIBS = @PTHREAD_LIBS@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
SED = @SED@
|
SED = @SED@
|
||||||
|
@ -308,7 +312,6 @@ ctags CTAGS:
|
||||||
|
|
||||||
cscope cscopelist:
|
cscope cscopelist:
|
||||||
|
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
distdir: $(BUILT_SOURCES)
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#
|
#
|
||||||
# List of readers supported by the CCID driver
|
# List of readers supported by the CCID driver
|
||||||
# Generated: 2021-08-30
|
# Generated: 2022-01-27
|
||||||
#
|
#
|
||||||
# DO NOT EDIT BY HAND
|
# DO NOT EDIT BY HAND
|
||||||
|
|
||||||
|
@ -131,6 +131,7 @@
|
||||||
# ACS
|
# ACS
|
||||||
0x072F:0x1204:ACS ACR101 ICC Reader
|
0x072F:0x1204:ACS ACR101 ICC Reader
|
||||||
0x072F:0x221A:ACS ACR1251 Dual Reader
|
0x072F:0x221A:ACS ACR1251 Dual Reader
|
||||||
|
0x072F:0x2224:ACS ACR1281U
|
||||||
0x072F:0x223B:ACS ACR1252 Dual Reader
|
0x072F:0x223B:ACS ACR1252 Dual Reader
|
||||||
0x072F:0x223E:ACS ACR1252 Reader
|
0x072F:0x223E:ACS ACR1252 Reader
|
||||||
0x072F:0x223F:ACS ACR1255U-J1
|
0x072F:0x223F:ACS ACR1255U-J1
|
||||||
|
@ -314,16 +315,27 @@
|
||||||
|
|
||||||
# Circle
|
# Circle
|
||||||
0x31AA:0x0224:Circle Idaxis SecurePIV
|
0x31AA:0x0224:Circle Idaxis SecurePIV
|
||||||
|
0x31AA:0x0324:Circle CIR315
|
||||||
0x31AA:0x1000:Circle CIR115 ICC
|
0x31AA:0x1000:Circle CIR115 ICC
|
||||||
|
0x31AA:0x1100:Circle CIR125 ICC
|
||||||
0x31AA:0x2000:Circle CIR215 PICC
|
0x31AA:0x2000:Circle CIR215 PICC
|
||||||
0x31AA:0x2001:Circle CIR215 CL
|
0x31AA:0x2001:Circle CIR215 CL
|
||||||
|
0x31AA:0x2100:Circle CIR215 CL
|
||||||
0x31AA:0x3000:Circle CIR315 Dual & 1S
|
0x31AA:0x3000:Circle CIR315 Dual & 1S
|
||||||
0x31AA:0x3001:Circle CIR315
|
0x31AA:0x3001:Circle CIR315
|
||||||
0x31AA:0x3002:Circle CIR315 CL
|
0x31AA:0x3002:Circle CIR315 CL
|
||||||
|
0x31AA:0x3003:Circle CIR315 DI
|
||||||
0x31AA:0x3100:Circle CIR315
|
0x31AA:0x3100:Circle CIR315
|
||||||
0x31AA:0x4000:Circle CIR415 CL & 1S
|
0x31AA:0x4000:Circle CIR415 CL & 1S
|
||||||
|
0x31AA:0x4001:Circle CIR415 CL
|
||||||
|
0x31AA:0x5000:Circle CIR515 ICC
|
||||||
|
0x31AA:0x6000:Circle CIR615 CL & 1S
|
||||||
|
0x31AA:0x6001:Circle CIR615 CL
|
||||||
0x31AA:0x7001:Circle CCR7115 ICC
|
0x31AA:0x7001:Circle CCR7115 ICC
|
||||||
0x31AA:0x7003:Circle CCR7315
|
0x31AA:0x7003:Circle CCR7315
|
||||||
|
0x31AA:0x7004:Circle CIR315
|
||||||
|
0x31AA:0x7005:Circle CCR7125 ICC
|
||||||
|
0x31AA:0x7006:Circle CIR125-DOT ICC
|
||||||
|
|
||||||
# COVADIS
|
# COVADIS
|
||||||
0x0982:0x0008:COVADIS VEGA-ALPHA
|
0x0982:0x0008:COVADIS VEGA-ALPHA
|
||||||
|
@ -354,6 +366,9 @@
|
||||||
0x09D8:0x0427:Elatec TWN4 SmartCard NFC
|
0x09D8:0x0427:Elatec TWN4 SmartCard NFC
|
||||||
0x09D8:0x0428:Elatec TWN4/B1.06/CPF3.05/S1SC1.32/P (Beta 3)
|
0x09D8:0x0428:Elatec TWN4/B1.06/CPF3.05/S1SC1.32/P (Beta 3)
|
||||||
|
|
||||||
|
# ELYCTIS
|
||||||
|
0x1FFA:0x0002:ELYCTIS CL reader
|
||||||
|
|
||||||
# ESMART
|
# ESMART
|
||||||
0x2CE4:0x7479:ESMART Token GOST
|
0x2CE4:0x7479:ESMART Token GOST
|
||||||
|
|
||||||
|
@ -638,6 +653,7 @@
|
||||||
0x20A0:0x4109:Nitrokey Nitrokey Storage
|
0x20A0:0x4109:Nitrokey Nitrokey Storage
|
||||||
0x20A0:0x4211:Nitrokey Nitrokey Start
|
0x20A0:0x4211:Nitrokey Nitrokey Start
|
||||||
0x20A0:0x4230:Nitrokey Nitrokey HSM
|
0x20A0:0x4230:Nitrokey Nitrokey HSM
|
||||||
|
0x20A0:0x42B2:Nitrokey Nitrokey 3
|
||||||
|
|
||||||
# NTT Communications Corp.
|
# NTT Communications Corp.
|
||||||
0x04E6:0x511A:NTT Communications Corp. SCR3310-NTTCom USB SmartCard Reader
|
0x04E6:0x511A:NTT Communications Corp. SCR3310-NTTCom USB SmartCard Reader
|
||||||
|
@ -750,9 +766,9 @@
|
||||||
0x1209:0xBEEE:SoloKeys Solo 2
|
0x1209:0xBEEE:SoloKeys Solo 2
|
||||||
|
|
||||||
# SONY
|
# SONY
|
||||||
0x054C:0x0D8F:SONY Felica RC-S660/U
|
0x054C:0x0D8F:SONY FeliCa RC-S660/U
|
||||||
0x054C:0x0DC8:SONY Felica RC-S300/S
|
0x054C:0x0DC8:SONY FeliCa RC-S300/S
|
||||||
0x054C:0x0DC9:SONY Felica RC-S300/P
|
0x054C:0x0DC9:SONY FeliCa RC-S300/P
|
||||||
|
|
||||||
# SPECINFOSYSTEMS
|
# SPECINFOSYSTEMS
|
||||||
0x316E:0x0001:SPECINFOSYSTEMS DIAMOND token
|
0x316E:0x0001:SPECINFOSYSTEMS DIAMOND token
|
||||||
|
@ -806,6 +822,9 @@
|
||||||
# Teridian Semiconductors
|
# Teridian Semiconductors
|
||||||
0x1862:0x0000:Teridian Semiconductors TSC12xxFV.09
|
0x1862:0x0000:Teridian Semiconductors TSC12xxFV.09
|
||||||
|
|
||||||
|
# Thales
|
||||||
|
0x08E6:0x34C7:Thales Shield M4 Reader
|
||||||
|
|
||||||
# THURSBY SOFTWARE
|
# THURSBY SOFTWARE
|
||||||
0x1976:0x0001:THURSBY SOFTWARE TSS-PK1
|
0x1976:0x0001:THURSBY SOFTWARE TSS-PK1
|
||||||
|
|
||||||
|
@ -878,6 +897,8 @@
|
||||||
0x1050:0x0406:Yubico YubiKey FIDO+CCID
|
0x1050:0x0406:Yubico YubiKey FIDO+CCID
|
||||||
0x1050:0x0407:Yubico YubiKey OTP+FIDO+CCID
|
0x1050:0x0407:Yubico YubiKey OTP+FIDO+CCID
|
||||||
|
|
||||||
|
# ~ELYCTIS
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
# section: unsupported
|
# section: unsupported
|
||||||
##########################
|
##########################
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
# Makefile.in generated by automake 1.16.5 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -306,8 +306,6 @@ am__define_uniq_tagged_files = \
|
||||||
unique=`for i in $$list; do \
|
unique=`for i in $$list; do \
|
||||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
done | $(am__uniquify_input)`
|
done | $(am__uniquify_input)`
|
||||||
ETAGS = etags
|
|
||||||
CTAGS = ctags
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
|
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
|
||||||
$(top_srcdir)/ylwrap tokenparser.c
|
$(top_srcdir)/ylwrap tokenparser.c
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
@ -325,6 +323,8 @@ CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
CPP = @CPP@
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CSCOPE = @CSCOPE@
|
||||||
|
CTAGS = @CTAGS@
|
||||||
CYGPATH_W = @CYGPATH_W@
|
CYGPATH_W = @CYGPATH_W@
|
||||||
DEFS = @DEFS@
|
DEFS = @DEFS@
|
||||||
DEPDIR = @DEPDIR@
|
DEPDIR = @DEPDIR@
|
||||||
|
@ -336,6 +336,7 @@ ECHO_C = @ECHO_C@
|
||||||
ECHO_N = @ECHO_N@
|
ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
EGREP = @EGREP@
|
EGREP = @EGREP@
|
||||||
|
ETAGS = @ETAGS@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
FGREP = @FGREP@
|
FGREP = @FGREP@
|
||||||
GREP = @GREP@
|
GREP = @GREP@
|
||||||
|
@ -385,6 +386,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
PTHREAD_CC = @PTHREAD_CC@
|
PTHREAD_CC = @PTHREAD_CC@
|
||||||
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
||||||
|
PTHREAD_CXX = @PTHREAD_CXX@
|
||||||
PTHREAD_LIBS = @PTHREAD_LIBS@
|
PTHREAD_LIBS = @PTHREAD_LIBS@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
SED = @SED@
|
SED = @SED@
|
||||||
|
@ -1052,7 +1054,6 @@ cscopelist-am: $(am__tagged_files)
|
||||||
|
|
||||||
distclean-tags:
|
distclean-tags:
|
||||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
distdir: $(BUILT_SOURCES)
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
|
|
@ -576,6 +576,14 @@ int ccid_open_hack_post(unsigned int reader_index)
|
||||||
* have one */
|
* have one */
|
||||||
ccid_descriptor->bPINSupport = 0;
|
ccid_descriptor->bPINSupport = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SAFENET_ETOKEN_5100:
|
||||||
|
/* the old SafeNet eToken 5110 SC (firmware 0.12 & 0.13)
|
||||||
|
* does not like IFSD negotiation. So disable it. */
|
||||||
|
if ((0x0012 == ccid_descriptor->IFD_bcdDevice)
|
||||||
|
|| (0x0013 == ccid_descriptor->IFD_bcdDevice))
|
||||||
|
ccid_descriptor->dwFeatures |= CCID_CLASS_AUTO_IFSD;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gemalto readers may report additional information */
|
/* Gemalto readers may report additional information */
|
||||||
|
|
|
@ -70,6 +70,11 @@ typedef struct
|
||||||
*/
|
*/
|
||||||
char bMaxSlotIndex;
|
char bMaxSlotIndex;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum number of slots which can be simultaneously busy
|
||||||
|
*/
|
||||||
|
char bMaxCCIDBusySlots;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Slot in use
|
* Slot in use
|
||||||
*/
|
*/
|
||||||
|
@ -232,6 +237,7 @@ typedef struct
|
||||||
#define HID_OMNIKEY_5422 0x076B5422
|
#define HID_OMNIKEY_5422 0x076B5422
|
||||||
#define HID_OMNIKEY_3X21 0x076B3031 /* OMNIKEY 3121 or 3021 or 1021 */
|
#define HID_OMNIKEY_3X21 0x076B3031 /* OMNIKEY 3121 or 3021 or 1021 */
|
||||||
#define HID_OMNIKEY_3821 0x076B3821 /* OMNIKEY 3821 */
|
#define HID_OMNIKEY_3821 0x076B3821 /* OMNIKEY 3821 */
|
||||||
|
#define HID_OMNIKEY_5427CK 0x076B5427 /* OMNIKEY 5427 CK */
|
||||||
#define HID_OMNIKEY_6121 0x076B6632 /* OMNIKEY 6121 */
|
#define HID_OMNIKEY_6121 0x076B6632 /* OMNIKEY 6121 */
|
||||||
#define CHERRY_XX44 0x046A00A7 /* Cherry Smart Terminal xx44 */
|
#define CHERRY_XX44 0x046A00A7 /* Cherry Smart Terminal xx44 */
|
||||||
#define FUJITSU_D323 0x0BF81024 /* Fujitsu Smartcard Reader D323 */
|
#define FUJITSU_D323 0x0BF81024 /* Fujitsu Smartcard Reader D323 */
|
||||||
|
@ -239,6 +245,7 @@ typedef struct
|
||||||
#define IDENTIV_uTrust3701F 0x04E65791
|
#define IDENTIV_uTrust3701F 0x04E65791
|
||||||
#define IDENTIV_uTrust4701F 0x04E65724
|
#define IDENTIV_uTrust4701F 0x04E65724
|
||||||
#define BIT4ID_MINILECTOR 0x25DD3111
|
#define BIT4ID_MINILECTOR 0x25DD3111
|
||||||
|
#define SAFENET_ETOKEN_5100 0x05290620
|
||||||
|
|
||||||
#define VENDOR_GEMALTO 0x08E6
|
#define VENDOR_GEMALTO 0x08E6
|
||||||
#define GET_VENDOR(readerID) ((readerID >> 16) & 0xFFFF)
|
#define GET_VENDOR(readerID) ((readerID >> 16) & 0xFFFF)
|
||||||
|
|
|
@ -220,7 +220,7 @@ status_t WriteSerial(unsigned int reader_index, unsigned int length,
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
status_t ReadSerial(unsigned int reader_index,
|
status_t ReadSerial(unsigned int reader_index,
|
||||||
unsigned int *length, unsigned char *buffer)
|
unsigned int *length, unsigned char *buffer, int bSeq)
|
||||||
{
|
{
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -228,6 +228,9 @@ status_t ReadSerial(unsigned int reader_index,
|
||||||
int to_read;
|
int to_read;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* ignore bSeq */
|
||||||
|
(void)bSeq;
|
||||||
|
|
||||||
/* we get the echo first */
|
/* we get the echo first */
|
||||||
echo = serialDevice[reader_index].echo;
|
echo = serialDevice[reader_index].echo;
|
||||||
|
|
||||||
|
@ -620,6 +623,7 @@ static status_t set_ccid_descriptor(unsigned int reader_index,
|
||||||
serialDevice[reader_index].ccid.bPINSupport = 0x0;
|
serialDevice[reader_index].ccid.bPINSupport = 0x0;
|
||||||
serialDevice[reader_index].ccid.dwMaxDataRate = 344086;
|
serialDevice[reader_index].ccid.dwMaxDataRate = 344086;
|
||||||
serialDevice[reader_index].ccid.bMaxSlotIndex = 0;
|
serialDevice[reader_index].ccid.bMaxSlotIndex = 0;
|
||||||
|
serialDevice[reader_index].ccid.bMaxCCIDBusySlots = 1;
|
||||||
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialTwinDataRates;
|
serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialTwinDataRates;
|
||||||
serialDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
|
serialDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
|
||||||
serialDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
|
serialDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
|
||||||
|
@ -934,6 +938,21 @@ status_t CloseSerial(unsigned int reader_index)
|
||||||
} /* CloseSerial */
|
} /* CloseSerial */
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* DisconnectSerial
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
status_t DisconnectSerial(unsigned int reader_index)
|
||||||
|
{
|
||||||
|
(void)reader_index;
|
||||||
|
|
||||||
|
DEBUG_COMM("Disconnect reader");
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
} /* DisconnectSerial */
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* get_ccid_descriptor
|
* get_ccid_descriptor
|
||||||
|
|
|
@ -28,8 +28,10 @@ status_t WriteSerial(unsigned int reader_index, unsigned int length,
|
||||||
unsigned char *Buffer);
|
unsigned char *Buffer);
|
||||||
|
|
||||||
status_t ReadSerial(unsigned int reader_index, unsigned int *length,
|
status_t ReadSerial(unsigned int reader_index, unsigned int *length,
|
||||||
unsigned char *Buffer);
|
unsigned char *Buffer, int bSeq);
|
||||||
|
|
||||||
status_t CloseSerial(unsigned int reader_index);
|
status_t CloseSerial(unsigned int reader_index);
|
||||||
|
|
||||||
|
status_t DisconnectSerial(unsigned int reader_index);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
370
src/ccid_usb.c
370
src/ccid_usb.c
|
@ -28,6 +28,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <ifdhandler.h>
|
#include <ifdhandler.h>
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
@ -61,18 +63,30 @@ libusb_context *ctx = NULL;
|
||||||
|
|
||||||
#define CCID_INTERRUPT_SIZE 8
|
#define CCID_INTERRUPT_SIZE 8
|
||||||
|
|
||||||
|
struct multiSlot_ConcurrentAccess
|
||||||
|
{
|
||||||
|
unsigned char buffer[10 + MAX_BUFFER_SIZE_EXTENDED];
|
||||||
|
int length;
|
||||||
|
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
pthread_cond_t condition;
|
||||||
|
};
|
||||||
|
|
||||||
struct usbDevice_MultiSlot_Extension
|
struct usbDevice_MultiSlot_Extension
|
||||||
{
|
{
|
||||||
int reader_index;
|
int reader_index;
|
||||||
|
|
||||||
/* The multi-threaded polling part */
|
/* The multi-threaded polling part */
|
||||||
int terminated;
|
_Atomic int terminated;
|
||||||
int status;
|
int status;
|
||||||
unsigned char buffer[CCID_INTERRUPT_SIZE];
|
unsigned char buffer[CCID_INTERRUPT_SIZE];
|
||||||
pthread_t thread_proc;
|
pthread_t thread_proc;
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
pthread_cond_t condition;
|
pthread_cond_t condition;
|
||||||
struct libusb_transfer *transfer;
|
|
||||||
|
pthread_t thread_concurrent;
|
||||||
|
struct multiSlot_ConcurrentAccess *concurrent;
|
||||||
|
libusb_device_handle *dev_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -99,11 +113,12 @@ typedef struct
|
||||||
_ccid_descriptor ccid;
|
_ccid_descriptor ccid;
|
||||||
|
|
||||||
/* libusb transfer for the polling (or NULL) */
|
/* libusb transfer for the polling (or NULL) */
|
||||||
struct libusb_transfer *polling_transfer;
|
_Atomic (struct libusb_transfer *) polling_transfer;
|
||||||
|
|
||||||
/* pointer to the multislot extension (if any) */
|
/* pointer to the multislot extension (if any) */
|
||||||
struct usbDevice_MultiSlot_Extension *multislot_extension;
|
struct usbDevice_MultiSlot_Extension *multislot_extension;
|
||||||
|
|
||||||
|
char disconnected;
|
||||||
} _usbDevice;
|
} _usbDevice;
|
||||||
|
|
||||||
/* The _usbDevice structure must be defined before including ccid_usb.h */
|
/* The _usbDevice structure must be defined before including ccid_usb.h */
|
||||||
|
@ -399,7 +414,7 @@ again_libusb:
|
||||||
if ((device_bus || device_addr)
|
if ((device_bus || device_addr)
|
||||||
&& ((bus_number != device_bus)
|
&& ((bus_number != device_bus)
|
||||||
|| (device_address != device_addr))) {
|
|| (device_address != device_addr))) {
|
||||||
/* not USB the device we are looking for */
|
/* not the USB device we are looking for */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -543,7 +558,7 @@ again_libusb:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* if an interface number is given by HAL we
|
/* if an interface number is given by udev we
|
||||||
* continue with this device. */
|
* continue with this device. */
|
||||||
if (-1 == interface_number)
|
if (-1 == interface_number)
|
||||||
{
|
{
|
||||||
|
@ -701,7 +716,8 @@ again:
|
||||||
usbDevice[reader_index].interface = interface;
|
usbDevice[reader_index].interface = interface;
|
||||||
usbDevice[reader_index].real_nb_opened_slots = 1;
|
usbDevice[reader_index].real_nb_opened_slots = 1;
|
||||||
usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
|
usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
|
||||||
usbDevice[reader_index].polling_transfer = NULL;
|
atomic_init(&usbDevice[reader_index].polling_transfer, NULL);
|
||||||
|
usbDevice[reader_index].disconnected = FALSE;
|
||||||
|
|
||||||
/* CCID common informations */
|
/* CCID common informations */
|
||||||
usbDevice[reader_index].ccid.real_bSeq = 0;
|
usbDevice[reader_index].ccid.real_bSeq = 0;
|
||||||
|
@ -717,6 +733,7 @@ again:
|
||||||
usbDevice[reader_index].ccid.dwDefaultClock = dw2i(device_descriptor, 10);
|
usbDevice[reader_index].ccid.dwDefaultClock = dw2i(device_descriptor, 10);
|
||||||
usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(device_descriptor, 23);
|
usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(device_descriptor, 23);
|
||||||
usbDevice[reader_index].ccid.bMaxSlotIndex = device_descriptor[4];
|
usbDevice[reader_index].ccid.bMaxSlotIndex = device_descriptor[4];
|
||||||
|
usbDevice[reader_index].ccid.bMaxCCIDBusySlots = device_descriptor[53];
|
||||||
usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
|
usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
|
||||||
usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
|
usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
|
||||||
if (device_descriptor[27])
|
if (device_descriptor[27])
|
||||||
|
@ -840,6 +857,12 @@ status_t WriteUSB(unsigned int reader_index, unsigned int length,
|
||||||
(void)snprintf(debug_header, sizeof(debug_header), "-> %06X ",
|
(void)snprintf(debug_header, sizeof(debug_header), "-> %06X ",
|
||||||
(int)reader_index);
|
(int)reader_index);
|
||||||
|
|
||||||
|
if (usbDevice[reader_index].disconnected)
|
||||||
|
{
|
||||||
|
DEBUG_COMM("Reader disconnected");
|
||||||
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_ZLP
|
#ifdef ENABLE_ZLP
|
||||||
if (usbDevice[reader_index].ccid.zlp)
|
if (usbDevice[reader_index].ccid.zlp)
|
||||||
{ /* Zero Length Packet */
|
{ /* Zero Length Packet */
|
||||||
|
@ -860,9 +883,9 @@ status_t WriteUSB(unsigned int reader_index, unsigned int length,
|
||||||
|
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
{
|
{
|
||||||
DEBUG_CRITICAL5("write failed (%d/%d): %d %s",
|
DEBUG_CRITICAL4("write failed (%d/%d): %s",
|
||||||
usbDevice[reader_index].bus_number,
|
usbDevice[reader_index].bus_number,
|
||||||
usbDevice[reader_index].device_address, rv, libusb_error_name(rv));
|
usbDevice[reader_index].device_address, libusb_error_name(rv));
|
||||||
|
|
||||||
if (LIBUSB_ERROR_NO_DEVICE == rv)
|
if (LIBUSB_ERROR_NO_DEVICE == rv)
|
||||||
return STATUS_NO_SUCH_DEVICE;
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
|
@ -880,42 +903,113 @@ status_t WriteUSB(unsigned int reader_index, unsigned int length,
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
status_t ReadUSB(unsigned int reader_index, unsigned int * length,
|
status_t ReadUSB(unsigned int reader_index, unsigned int * length,
|
||||||
unsigned char *buffer)
|
unsigned char *buffer, int bSeq)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
int actual_length;
|
int actual_length;
|
||||||
char debug_header[] = "<- 121234 ";
|
char debug_header[] = "<- 121234 ";
|
||||||
_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
|
|
||||||
int duplicate_frame = 0;
|
int duplicate_frame = 0;
|
||||||
|
|
||||||
|
if (usbDevice[reader_index].disconnected)
|
||||||
|
{
|
||||||
|
DEBUG_COMM("Reader disconnected");
|
||||||
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
read_again:
|
read_again:
|
||||||
(void)snprintf(debug_header, sizeof(debug_header), "<- %06X ",
|
(void)snprintf(debug_header, sizeof(debug_header), "<- %06X ",
|
||||||
(int)reader_index);
|
(int)reader_index);
|
||||||
|
|
||||||
rv = libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
|
if (usbDevice[reader_index].multislot_extension)
|
||||||
usbDevice[reader_index].bulk_in, buffer, *length,
|
|
||||||
&actual_length, usbDevice[reader_index].ccid.readTimeout);
|
|
||||||
|
|
||||||
if (rv < 0)
|
|
||||||
{
|
{
|
||||||
*length = 0;
|
/* multi slot read */
|
||||||
DEBUG_CRITICAL5("read failed (%d/%d): %d %s",
|
int slot = usbDevice[reader_index].ccid.bCurrentSlotIndex;
|
||||||
usbDevice[reader_index].bus_number,
|
struct multiSlot_ConcurrentAccess *concurrent = usbDevice[reader_index].multislot_extension->concurrent;
|
||||||
usbDevice[reader_index].device_address, rv, libusb_error_name(rv));
|
|
||||||
|
|
||||||
if (LIBUSB_ERROR_NO_DEVICE == rv)
|
rv = 0;
|
||||||
return STATUS_NO_SUCH_DEVICE;
|
pthread_mutex_lock(&concurrent[slot].mutex);
|
||||||
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
/* a frame is available? */
|
||||||
|
if (0 == concurrent[slot].length)
|
||||||
|
{
|
||||||
|
struct timespec timeout;
|
||||||
|
time_t timeout_sec = usbDevice[reader_index].ccid.readTimeout / 1000;
|
||||||
|
long timeout_msec = usbDevice[reader_index].ccid.readTimeout - timeout_sec * 1000;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_REALTIME, &timeout);
|
||||||
|
timeout.tv_sec += timeout_sec;
|
||||||
|
timeout.tv_nsec += timeout_msec * 1000 * 1000;
|
||||||
|
if (timeout.tv_nsec > 1000 * 1000 * 1000)
|
||||||
|
{
|
||||||
|
timeout.tv_sec++;
|
||||||
|
timeout.tv_nsec -= 1000 * 1000 * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait for a new frame */
|
||||||
|
DEBUG_COMM2("Waiting data for slot %d", slot);
|
||||||
|
rv = pthread_cond_timedwait(&concurrent[slot].condition,
|
||||||
|
&concurrent[slot].mutex, &timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rv)
|
||||||
|
{
|
||||||
|
*length = 0;
|
||||||
|
DEBUG_CRITICAL5("read failed (%d/%d): %d %s",
|
||||||
|
usbDevice[reader_index].bus_number,
|
||||||
|
usbDevice[reader_index].device_address, rv, strerror(rv));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_COMM3("Got %d bytes for slot %d", concurrent[slot].length,
|
||||||
|
slot);
|
||||||
|
if (concurrent[slot].length > 0)
|
||||||
|
{
|
||||||
|
if (concurrent[slot].length > (int)*length)
|
||||||
|
DEBUG_CRITICAL3("Received %d bytes but expected only %d",
|
||||||
|
concurrent[slot].length, *length);
|
||||||
|
else
|
||||||
|
*length = concurrent[slot].length;
|
||||||
|
memcpy(buffer, concurrent[slot].buffer, *length);
|
||||||
|
concurrent[slot].length = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rv = EINTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&concurrent[slot].mutex);
|
||||||
|
|
||||||
|
if (rv)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rv = libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
|
||||||
|
usbDevice[reader_index].bulk_in, buffer, *length,
|
||||||
|
&actual_length, usbDevice[reader_index].ccid.readTimeout);
|
||||||
|
|
||||||
*length = actual_length;
|
if (rv < 0)
|
||||||
|
{
|
||||||
|
*length = 0;
|
||||||
|
DEBUG_CRITICAL4("read failed (%d/%d): %s",
|
||||||
|
usbDevice[reader_index].bus_number,
|
||||||
|
usbDevice[reader_index].device_address,
|
||||||
|
libusb_error_name(rv));
|
||||||
|
|
||||||
|
if (LIBUSB_ERROR_NO_DEVICE == rv)
|
||||||
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*length = actual_length;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_XXD(debug_header, buffer, *length);
|
DEBUG_XXD(debug_header, buffer, *length);
|
||||||
|
|
||||||
#define BSEQ_OFFSET 6
|
#define BSEQ_OFFSET 6
|
||||||
if ((*length >= BSEQ_OFFSET +1)
|
if ((*length >= BSEQ_OFFSET +1)
|
||||||
&& (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))
|
&& (bSeq != -1)
|
||||||
|
&& (buffer[BSEQ_OFFSET] != bSeq))
|
||||||
{
|
{
|
||||||
duplicate_frame++;
|
duplicate_frame++;
|
||||||
if (duplicate_frame > 10)
|
if (duplicate_frame > 10)
|
||||||
|
@ -923,7 +1017,7 @@ read_again:
|
||||||
DEBUG_CRITICAL("Too many duplicate frame detected");
|
DEBUG_CRITICAL("Too many duplicate frame detected");
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
DEBUG_INFO1("Duplicate frame detected");
|
DEBUG_INFO1("Invalid frame detected");
|
||||||
goto read_again;
|
goto read_again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,6 +1054,8 @@ status_t CloseUSB(unsigned int reader_index)
|
||||||
/* If this is a multislot reader, close using the multislot stuff */
|
/* If this is a multislot reader, close using the multislot stuff */
|
||||||
if (msExt)
|
if (msExt)
|
||||||
{
|
{
|
||||||
|
struct multiSlot_ConcurrentAccess *concurrent;
|
||||||
|
|
||||||
/* terminate the interrupt waiter thread */
|
/* terminate the interrupt waiter thread */
|
||||||
Multi_PollingTerminate(msExt);
|
Multi_PollingTerminate(msExt);
|
||||||
|
|
||||||
|
@ -970,6 +1066,19 @@ status_t CloseUSB(unsigned int reader_index)
|
||||||
pthread_cond_destroy(&msExt->condition);
|
pthread_cond_destroy(&msExt->condition);
|
||||||
pthread_mutex_destroy(&msExt->mutex);
|
pthread_mutex_destroy(&msExt->mutex);
|
||||||
|
|
||||||
|
/* wait for the thread to actually terminate */
|
||||||
|
pthread_join(msExt->thread_concurrent, NULL);
|
||||||
|
|
||||||
|
concurrent = msExt->concurrent;
|
||||||
|
for (int slot=0; slot<=usbDevice[reader_index].ccid.bMaxSlotIndex;
|
||||||
|
slot++)
|
||||||
|
{
|
||||||
|
/* Create mutex and condition object for the concurrent read */
|
||||||
|
pthread_cond_destroy(&concurrent[slot].condition);
|
||||||
|
pthread_mutex_destroy(&concurrent[slot].mutex);
|
||||||
|
}
|
||||||
|
free(concurrent);
|
||||||
|
|
||||||
/* Deallocate the extension itself */
|
/* Deallocate the extension itself */
|
||||||
free(msExt);
|
free(msExt);
|
||||||
|
|
||||||
|
@ -1004,6 +1113,29 @@ status_t CloseUSB(unsigned int reader_index)
|
||||||
} /* CloseUSB */
|
} /* CloseUSB */
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* DisconnectUSB
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
status_t DisconnectUSB(unsigned int reader_index)
|
||||||
|
{
|
||||||
|
DEBUG_COMM("Disconnect reader");
|
||||||
|
libusb_device_handle * dev_handle = usbDevice[reader_index].dev_handle;
|
||||||
|
|
||||||
|
for (int i=0; i<CCID_DRIVER_MAX_READERS; i++)
|
||||||
|
{
|
||||||
|
if (usbDevice[i].dev_handle == dev_handle)
|
||||||
|
{
|
||||||
|
DEBUG_COMM2("Disconnect reader: %d", i);
|
||||||
|
usbDevice[i].disconnected = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
} /* DisconnectUSB */
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* get_ccid_descriptor
|
* get_ccid_descriptor
|
||||||
|
@ -1295,9 +1427,10 @@ int ControlUSB(int reader_index, int requesttype, int request, int value,
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DEBUG_CRITICAL5("control failed (%d/%d): %d %s",
|
DEBUG_CRITICAL4("control failed (%d/%d): %s",
|
||||||
usbDevice[reader_index].bus_number,
|
usbDevice[reader_index].bus_number,
|
||||||
usbDevice[reader_index].device_address, ret, libusb_error_name(ret));
|
usbDevice[reader_index].device_address,
|
||||||
|
libusb_error_name(ret));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1357,7 +1490,7 @@ int InterruptRead(int reader_index, int timeout /* in ms */)
|
||||||
return IFD_COMMUNICATION_ERROR;
|
return IFD_COMMUNICATION_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
usbDevice[reader_index].polling_transfer = transfer;
|
atomic_store(&usbDevice[reader_index].polling_transfer, transfer);
|
||||||
|
|
||||||
while (!completed)
|
while (!completed)
|
||||||
{
|
{
|
||||||
|
@ -1380,7 +1513,7 @@ int InterruptRead(int reader_index, int timeout /* in ms */)
|
||||||
actual_length = transfer->actual_length;
|
actual_length = transfer->actual_length;
|
||||||
ret = transfer->status;
|
ret = transfer->status;
|
||||||
|
|
||||||
usbDevice[reader_index].polling_transfer = NULL;
|
atomic_store(&usbDevice[reader_index].polling_transfer, NULL);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
|
|
||||||
DEBUG_PERIODIC3("after (%d) (%d)", reader_index, ret);
|
DEBUG_PERIODIC3("after (%d) (%d)", reader_index, ret);
|
||||||
|
@ -1396,9 +1529,10 @@ int InterruptRead(int reader_index, int timeout /* in ms */)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* if libusb_interrupt_transfer() times out we get EILSEQ or EAGAIN */
|
/* if libusb_interrupt_transfer() times out we get EILSEQ or EAGAIN */
|
||||||
DEBUG_COMM4("InterruptRead (%d/%d): %d",
|
DEBUG_COMM4("InterruptRead (%d/%d): %s",
|
||||||
usbDevice[reader_index].bus_number,
|
usbDevice[reader_index].bus_number,
|
||||||
usbDevice[reader_index].device_address, ret);
|
usbDevice[reader_index].device_address,
|
||||||
|
libusb_error_name(ret));
|
||||||
return_value = IFD_COMMUNICATION_ERROR;
|
return_value = IFD_COMMUNICATION_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1422,8 +1556,7 @@ void InterruptStop(int reader_index)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = usbDevice[reader_index].polling_transfer;
|
transfer = atomic_load(&usbDevice[reader_index].polling_transfer);
|
||||||
usbDevice[reader_index].polling_transfer = NULL;
|
|
||||||
if (transfer)
|
if (transfer)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1453,6 +1586,13 @@ static void *Multi_PollingProc(void *p_ext)
|
||||||
usbDevice[msExt->reader_index].bus_number,
|
usbDevice[msExt->reader_index].bus_number,
|
||||||
usbDevice[msExt->reader_index].device_address);
|
usbDevice[msExt->reader_index].device_address);
|
||||||
|
|
||||||
|
transfer = libusb_alloc_transfer(0);
|
||||||
|
if (NULL == transfer)
|
||||||
|
{
|
||||||
|
DEBUG_COMM("libusb_alloc_transfer error");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
rv = 0;
|
rv = 0;
|
||||||
while (!msExt->terminated)
|
while (!msExt->terminated)
|
||||||
{
|
{
|
||||||
|
@ -1460,15 +1600,6 @@ static void *Multi_PollingProc(void *p_ext)
|
||||||
usbDevice[msExt->reader_index].bus_number,
|
usbDevice[msExt->reader_index].bus_number,
|
||||||
usbDevice[msExt->reader_index].device_address);
|
usbDevice[msExt->reader_index].device_address);
|
||||||
|
|
||||||
transfer = libusb_alloc_transfer(0);
|
|
||||||
if (NULL == transfer)
|
|
||||||
{
|
|
||||||
rv = LIBUSB_ERROR_NO_MEM;
|
|
||||||
DEBUG_COMM3("libusb_alloc_transfer err %d %s", rv,
|
|
||||||
libusb_error_name(rv));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer,
|
libusb_fill_bulk_transfer(transfer,
|
||||||
usbDevice[msExt->reader_index].dev_handle,
|
usbDevice[msExt->reader_index].dev_handle,
|
||||||
usbDevice[msExt->reader_index].interrupt,
|
usbDevice[msExt->reader_index].interrupt,
|
||||||
|
@ -1480,13 +1611,13 @@ static void *Multi_PollingProc(void *p_ext)
|
||||||
rv = libusb_submit_transfer(transfer);
|
rv = libusb_submit_transfer(transfer);
|
||||||
if (rv)
|
if (rv)
|
||||||
{
|
{
|
||||||
libusb_free_transfer(transfer);
|
DEBUG_COMM2("libusb_submit_transfer err %s",
|
||||||
DEBUG_COMM3("libusb_submit_transfer err %d %s", rv,
|
|
||||||
libusb_error_name(rv));
|
libusb_error_name(rv));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
usbDevice[msExt->reader_index].polling_transfer = transfer;
|
atomic_store(&usbDevice[msExt->reader_index].polling_transfer,
|
||||||
|
transfer);
|
||||||
|
|
||||||
completed = 0;
|
completed = 0;
|
||||||
while (!completed && !msExt->terminated)
|
while (!completed && !msExt->terminated)
|
||||||
|
@ -1494,7 +1625,7 @@ static void *Multi_PollingProc(void *p_ext)
|
||||||
rv = libusb_handle_events_completed(ctx, &completed);
|
rv = libusb_handle_events_completed(ctx, &completed);
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
{
|
{
|
||||||
DEBUG_COMM3("libusb_handle_events err %d %s", rv,
|
DEBUG_COMM2("libusb_handle_events err %s",
|
||||||
libusb_error_name(rv));
|
libusb_error_name(rv));
|
||||||
|
|
||||||
if (rv == LIBUSB_ERROR_INTERRUPTED)
|
if (rv == LIBUSB_ERROR_INTERRUPTED)
|
||||||
|
@ -1512,19 +1643,16 @@ static void *Multi_PollingProc(void *p_ext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
usbDevice[msExt->reader_index].polling_transfer = NULL;
|
atomic_store(&usbDevice[msExt->reader_index].polling_transfer,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (rv < 0)
|
if (0 == rv)
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
int b, slot;
|
int b, slot;
|
||||||
|
|
||||||
actual_length = transfer->actual_length;
|
actual_length = transfer->actual_length;
|
||||||
status = transfer->status;
|
status = transfer->status;
|
||||||
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
|
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case LIBUSB_TRANSFER_COMPLETED:
|
case LIBUSB_TRANSFER_COMPLETED:
|
||||||
|
@ -1566,10 +1694,10 @@ static void *Multi_PollingProc(void *p_ext)
|
||||||
default:
|
default:
|
||||||
/* if libusb_interrupt_transfer() times out
|
/* if libusb_interrupt_transfer() times out
|
||||||
* we get EILSEQ or EAGAIN */
|
* we get EILSEQ or EAGAIN */
|
||||||
DEBUG_COMM4("Multi_PollingProc (%d/%d): %d",
|
DEBUG_COMM4("Multi_PollingProc (%d/%d): %s",
|
||||||
usbDevice[msExt->reader_index].bus_number,
|
usbDevice[msExt->reader_index].bus_number,
|
||||||
usbDevice[msExt->reader_index].device_address,
|
usbDevice[msExt->reader_index].device_address,
|
||||||
status);
|
libusb_error_name(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell other slots that there's a new interrupt buffer */
|
/* Tell other slots that there's a new interrupt buffer */
|
||||||
|
@ -1591,14 +1719,20 @@ static void *Multi_PollingProc(void *p_ext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msExt->terminated = TRUE;
|
libusb_free_transfer(transfer);
|
||||||
|
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
{
|
{
|
||||||
DEBUG_CRITICAL5("Multi_PollingProc (%d/%d): error %d %s",
|
if (rv != LIBUSB_ERROR_NO_DEVICE)
|
||||||
usbDevice[msExt->reader_index].bus_number,
|
DEBUG_CRITICAL4("Multi_PollingProc (%d/%d): error %s",
|
||||||
usbDevice[msExt->reader_index].device_address,
|
usbDevice[msExt->reader_index].bus_number,
|
||||||
rv, libusb_error_name(rv));
|
usbDevice[msExt->reader_index].device_address,
|
||||||
|
libusb_error_name(rv));
|
||||||
|
else
|
||||||
|
DEBUG_COMM4("Multi_PollingProc (%d/%d): error %s",
|
||||||
|
usbDevice[msExt->reader_index].bus_number,
|
||||||
|
usbDevice[msExt->reader_index].device_address,
|
||||||
|
libusb_error_name(rv));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wake up the slot threads so they will exit as well */
|
/* Wake up the slot threads so they will exit as well */
|
||||||
|
@ -1616,6 +1750,7 @@ static void *Multi_PollingProc(void *p_ext)
|
||||||
/* Unlock */
|
/* Unlock */
|
||||||
pthread_mutex_unlock(&msExt->mutex);
|
pthread_mutex_unlock(&msExt->mutex);
|
||||||
|
|
||||||
|
end:
|
||||||
/* Now exit */
|
/* Now exit */
|
||||||
DEBUG_COMM3("Multi_PollingProc (%d/%d): Thread terminated",
|
DEBUG_COMM3("Multi_PollingProc (%d/%d): Thread terminated",
|
||||||
usbDevice[msExt->reader_index].bus_number,
|
usbDevice[msExt->reader_index].bus_number,
|
||||||
|
@ -1639,7 +1774,7 @@ static void Multi_PollingTerminate(struct usbDevice_MultiSlot_Extension *msExt)
|
||||||
{
|
{
|
||||||
msExt->terminated = TRUE;
|
msExt->terminated = TRUE;
|
||||||
|
|
||||||
transfer = usbDevice[msExt->reader_index].polling_transfer;
|
transfer = atomic_load(&usbDevice[msExt->reader_index].polling_transfer);
|
||||||
|
|
||||||
if (transfer)
|
if (transfer)
|
||||||
{
|
{
|
||||||
|
@ -1668,9 +1803,9 @@ static int Multi_InterruptRead(int reader_index, int timeout /* in ms */)
|
||||||
|
|
||||||
msExt = usbDevice[reader_index].multislot_extension;
|
msExt = usbDevice[reader_index].multislot_extension;
|
||||||
|
|
||||||
/* When stopped, return 0 so IFDHPolling will return IFD_NO_SUCH_DEVICE */
|
/* When stopped, returns IFD_NO_SUCH_DEVICE */
|
||||||
if ((msExt == NULL) || msExt->terminated)
|
if ((msExt == NULL) || msExt->terminated)
|
||||||
return 0;
|
return IFD_NO_SUCH_DEVICE;
|
||||||
|
|
||||||
DEBUG_PERIODIC3("Multi_InterruptRead (%d), timeout: %d ms",
|
DEBUG_PERIODIC3("Multi_InterruptRead (%d), timeout: %d ms",
|
||||||
reader_index, timeout);
|
reader_index, timeout);
|
||||||
|
@ -1708,9 +1843,9 @@ again:
|
||||||
/* Don't forget to unlock the mutex */
|
/* Don't forget to unlock the mutex */
|
||||||
pthread_mutex_unlock(&msExt->mutex);
|
pthread_mutex_unlock(&msExt->mutex);
|
||||||
|
|
||||||
/* When stopped, return 0 so IFDHPolling will return IFD_NO_SUCH_DEVICE */
|
/* When stopped, returns IFD_NO_SUCH_DEVICE */
|
||||||
if (msExt->terminated)
|
if (msExt->terminated)
|
||||||
return 0;
|
return IFD_NO_SUCH_DEVICE;
|
||||||
|
|
||||||
/* Not stopped */
|
/* Not stopped */
|
||||||
if (status == LIBUSB_TRANSFER_COMPLETED)
|
if (status == LIBUSB_TRANSFER_COMPLETED)
|
||||||
|
@ -1762,6 +1897,87 @@ static void Multi_InterruptStop(int reader_index)
|
||||||
} /* Multi_InterruptStop */
|
} /* Multi_InterruptStop */
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* Multi_ReadProc
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
static void *Multi_ReadProc(void *p_ext)
|
||||||
|
{
|
||||||
|
struct usbDevice_MultiSlot_Extension *msExt;
|
||||||
|
struct multiSlot_ConcurrentAccess *concurrent;
|
||||||
|
int reader_index;
|
||||||
|
int rv;
|
||||||
|
unsigned char buffer[10 + MAX_BUFFER_SIZE_EXTENDED];
|
||||||
|
int length;
|
||||||
|
|
||||||
|
msExt = p_ext;
|
||||||
|
concurrent = msExt->concurrent;
|
||||||
|
reader_index = msExt->reader_index;
|
||||||
|
|
||||||
|
DEBUG_COMM3("Multi_ReadProc (%d/%d): thread starting",
|
||||||
|
usbDevice[reader_index].bus_number,
|
||||||
|
usbDevice[reader_index].device_address);
|
||||||
|
|
||||||
|
while (! msExt->terminated)
|
||||||
|
{
|
||||||
|
int slot;
|
||||||
|
|
||||||
|
DEBUG_COMM2("Waiting read for reader %d", reader_index);
|
||||||
|
rv = libusb_bulk_transfer(msExt->dev_handle,
|
||||||
|
usbDevice[reader_index].bulk_in, buffer, sizeof buffer,
|
||||||
|
&length, 5 * 1000);
|
||||||
|
|
||||||
|
if (rv < 0)
|
||||||
|
{
|
||||||
|
/* timeout are expected since we read continuously */
|
||||||
|
if (LIBUSB_ERROR_TIMEOUT == rv)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (LIBUSB_ERROR_NO_DEVICE == rv)
|
||||||
|
{
|
||||||
|
DEBUG_INFO4("read failed (%d/%d): %s",
|
||||||
|
usbDevice[reader_index].bus_number,
|
||||||
|
usbDevice[reader_index].device_address,
|
||||||
|
libusb_error_name(rv));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_CRITICAL4("read failed (%d/%d): %s",
|
||||||
|
usbDevice[reader_index].bus_number,
|
||||||
|
usbDevice[reader_index].device_address,
|
||||||
|
libusb_error_name(rv));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait a bit to avoid a fast error loop */
|
||||||
|
(void)usleep(100*1000);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BSLOT_OFFSET 5
|
||||||
|
slot = buffer[BSLOT_OFFSET];
|
||||||
|
DEBUG_COMM3("Read %d bytes for slot %d", length, slot);
|
||||||
|
|
||||||
|
/* copy and signal */
|
||||||
|
pthread_mutex_lock(&concurrent[slot].mutex);
|
||||||
|
|
||||||
|
memcpy(concurrent[slot].buffer, buffer, length);
|
||||||
|
concurrent[slot].length = length;
|
||||||
|
pthread_cond_signal(&concurrent[slot].condition);
|
||||||
|
DEBUG_COMM3("Signaled reader %d slot %d", reader_index, slot);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&concurrent[slot].mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_COMM3("Multi_ReadProc (%d/%d): Thread terminated",
|
||||||
|
usbDevice[reader_index].bus_number,
|
||||||
|
usbDevice[reader_index].device_address);
|
||||||
|
|
||||||
|
pthread_exit(NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* Multi_CreateFirstSlot
|
* Multi_CreateFirstSlot
|
||||||
|
@ -1770,6 +1986,7 @@ static void Multi_InterruptStop(int reader_index)
|
||||||
static struct usbDevice_MultiSlot_Extension *Multi_CreateFirstSlot(int reader_index)
|
static struct usbDevice_MultiSlot_Extension *Multi_CreateFirstSlot(int reader_index)
|
||||||
{
|
{
|
||||||
struct usbDevice_MultiSlot_Extension *msExt;
|
struct usbDevice_MultiSlot_Extension *msExt;
|
||||||
|
struct multiSlot_ConcurrentAccess *concurrent;
|
||||||
|
|
||||||
/* Allocate a new extension buffer */
|
/* Allocate a new extension buffer */
|
||||||
msExt = malloc(sizeof(struct usbDevice_MultiSlot_Extension));
|
msExt = malloc(sizeof(struct usbDevice_MultiSlot_Extension));
|
||||||
|
@ -1779,17 +1996,38 @@ static struct usbDevice_MultiSlot_Extension *Multi_CreateFirstSlot(int reader_in
|
||||||
/* Remember the index */
|
/* Remember the index */
|
||||||
msExt->reader_index = reader_index;
|
msExt->reader_index = reader_index;
|
||||||
|
|
||||||
msExt->terminated = FALSE;
|
/* dev_handle of the physical reader */
|
||||||
|
msExt->dev_handle = usbDevice[reader_index].dev_handle;
|
||||||
|
|
||||||
|
atomic_init(&msExt->terminated, FALSE);
|
||||||
msExt->status = 0;
|
msExt->status = 0;
|
||||||
msExt->transfer = NULL;
|
|
||||||
|
|
||||||
/* Create mutex and condition object for the interrupt polling */
|
/* Create mutex and condition object for the interrupt polling */
|
||||||
pthread_mutex_init(&msExt->mutex, NULL);
|
pthread_mutex_init(&msExt->mutex, NULL);
|
||||||
pthread_cond_init(&msExt->condition, NULL);
|
pthread_cond_init(&msExt->condition, NULL);
|
||||||
|
|
||||||
|
/* concurrent USB read */
|
||||||
|
concurrent = calloc(usbDevice[reader_index].ccid.bMaxSlotIndex +1,
|
||||||
|
sizeof(struct multiSlot_ConcurrentAccess));
|
||||||
|
if (NULL == concurrent)
|
||||||
|
{
|
||||||
|
DEBUG_CRITICAL("malloc failed");
|
||||||
|
free(msExt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (int slot=0; slot<=usbDevice[reader_index].ccid.bMaxSlotIndex; slot++)
|
||||||
|
{
|
||||||
|
/* Create mutex and condition object for the concurrent read */
|
||||||
|
pthread_mutex_init(&concurrent[slot].mutex, NULL);
|
||||||
|
pthread_cond_init(&concurrent[slot].condition, NULL);
|
||||||
|
}
|
||||||
|
msExt->concurrent = concurrent;
|
||||||
|
|
||||||
/* create the thread in charge of the interrupt polling */
|
/* create the thread in charge of the interrupt polling */
|
||||||
pthread_create(&msExt->thread_proc, NULL, Multi_PollingProc, msExt);
|
pthread_create(&msExt->thread_proc, NULL, Multi_PollingProc, msExt);
|
||||||
|
|
||||||
|
pthread_create(&msExt->thread_concurrent, NULL, Multi_ReadProc, msExt);
|
||||||
|
|
||||||
return msExt;
|
return msExt;
|
||||||
} /* Multi_CreateFirstSlot */
|
} /* Multi_CreateFirstSlot */
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,10 @@ status_t WriteUSB(unsigned int reader_index, unsigned int length,
|
||||||
unsigned char *Buffer);
|
unsigned char *Buffer);
|
||||||
|
|
||||||
status_t ReadUSB(unsigned int reader_index, unsigned int *length,
|
status_t ReadUSB(unsigned int reader_index, unsigned int *length,
|
||||||
/*@out@*/ unsigned char *Buffer);
|
/*@out@*/ unsigned char *Buffer, int bSeq);
|
||||||
|
|
||||||
status_t CloseUSB(unsigned int reader_index);
|
status_t CloseUSB(unsigned int reader_index);
|
||||||
|
status_t DisconnectUSB(unsigned int reader_index);
|
||||||
|
|
||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
/*@null@*/ const struct libusb_interface *get_ccid_usb_interface(
|
/*@null@*/ const struct libusb_interface *get_ccid_usb_interface(
|
||||||
|
|
|
@ -95,6 +95,7 @@ RESPONSECODE CmdPowerOn(unsigned int reader_index, unsigned int * nlength,
|
||||||
unsigned char buffer[], int voltage)
|
unsigned char buffer[], int voltage)
|
||||||
{
|
{
|
||||||
unsigned char cmd[10];
|
unsigned char cmd[10];
|
||||||
|
int bSeq;
|
||||||
status_t res;
|
status_t res;
|
||||||
int length, count = 1;
|
int length, count = 1;
|
||||||
unsigned int atr_len;
|
unsigned int atr_len;
|
||||||
|
@ -218,10 +219,11 @@ check_again:
|
||||||
init_voltage = voltage;
|
init_voltage = voltage;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
|
bSeq = (*ccid_descriptor->pbSeq)++;
|
||||||
cmd[0] = 0x62; /* IccPowerOn */
|
cmd[0] = 0x62; /* IccPowerOn */
|
||||||
cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
|
cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
|
||||||
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
|
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
|
||||||
cmd[6] = (*ccid_descriptor->pbSeq)++;
|
cmd[6] = bSeq;
|
||||||
cmd[7] = voltage;
|
cmd[7] = voltage;
|
||||||
cmd[8] = cmd[9] = 0; /* RFU */
|
cmd[8] = cmd[9] = 0; /* RFU */
|
||||||
|
|
||||||
|
@ -232,7 +234,7 @@ again:
|
||||||
/* needed if we go back after a switch to ISO mode */
|
/* needed if we go back after a switch to ISO mode */
|
||||||
*nlength = length;
|
*nlength = length;
|
||||||
|
|
||||||
res = ReadPort(reader_index, nlength, buffer);
|
res = ReadPort(reader_index, nlength, buffer, bSeq);
|
||||||
CHECK_STATUS(res)
|
CHECK_STATUS(res)
|
||||||
|
|
||||||
if (*nlength < CCID_RESPONSE_HEADER_SIZE)
|
if (*nlength < CCID_RESPONSE_HEADER_SIZE)
|
||||||
|
@ -947,6 +949,7 @@ RESPONSECODE CmdEscapeCheck(unsigned int reader_index,
|
||||||
int mayfail)
|
int mayfail)
|
||||||
{
|
{
|
||||||
unsigned char *cmd_in, *cmd_out;
|
unsigned char *cmd_in, *cmd_out;
|
||||||
|
int bSeq;
|
||||||
status_t res;
|
status_t res;
|
||||||
unsigned int length_in, length_out;
|
unsigned int length_in, length_out;
|
||||||
RESPONSECODE return_value = IFD_SUCCESS;
|
RESPONSECODE return_value = IFD_SUCCESS;
|
||||||
|
@ -977,10 +980,11 @@ again:
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bSeq = (*ccid_descriptor->pbSeq)++;
|
||||||
cmd_in[0] = 0x6B; /* PC_to_RDR_Escape */
|
cmd_in[0] = 0x6B; /* PC_to_RDR_Escape */
|
||||||
i2dw(length_in - 10, cmd_in+1); /* dwLength */
|
i2dw(length_in - 10, cmd_in+1); /* dwLength */
|
||||||
cmd_in[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
|
cmd_in[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
|
||||||
cmd_in[6] = (*ccid_descriptor->pbSeq)++;
|
cmd_in[6] = bSeq;
|
||||||
cmd_in[7] = cmd_in[8] = cmd_in[9] = 0; /* RFU */
|
cmd_in[7] = cmd_in[8] = cmd_in[9] = 0; /* RFU */
|
||||||
|
|
||||||
/* copy the command */
|
/* copy the command */
|
||||||
|
@ -1000,7 +1004,7 @@ again:
|
||||||
|
|
||||||
time_request:
|
time_request:
|
||||||
length_out = 10 + *RxLength;
|
length_out = 10 + *RxLength;
|
||||||
res = ReadPort(reader_index, &length_out, cmd_out);
|
res = ReadPort(reader_index, &length_out, cmd_out, bSeq);
|
||||||
|
|
||||||
/* replay the command if NAK
|
/* replay the command if NAK
|
||||||
* This (generally) happens only for the first command sent to the reader
|
* This (generally) happens only for the first command sent to the reader
|
||||||
|
@ -1072,6 +1076,7 @@ end:
|
||||||
RESPONSECODE CmdPowerOff(unsigned int reader_index)
|
RESPONSECODE CmdPowerOff(unsigned int reader_index)
|
||||||
{
|
{
|
||||||
unsigned char cmd[10];
|
unsigned char cmd[10];
|
||||||
|
int bSeq;
|
||||||
status_t res;
|
status_t res;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
RESPONSECODE return_value = IFD_SUCCESS;
|
RESPONSECODE return_value = IFD_SUCCESS;
|
||||||
|
@ -1124,17 +1129,18 @@ RESPONSECODE CmdPowerOff(unsigned int reader_index)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bSeq = (*ccid_descriptor->pbSeq)++;
|
||||||
cmd[0] = 0x63; /* IccPowerOff */
|
cmd[0] = 0x63; /* IccPowerOff */
|
||||||
cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
|
cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
|
||||||
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
|
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
|
||||||
cmd[6] = (*ccid_descriptor->pbSeq)++;
|
cmd[6] = bSeq;
|
||||||
cmd[7] = cmd[8] = cmd[9] = 0; /* RFU */
|
cmd[7] = cmd[8] = cmd[9] = 0; /* RFU */
|
||||||
|
|
||||||
res = WritePort(reader_index, sizeof(cmd), cmd);
|
res = WritePort(reader_index, sizeof(cmd), cmd);
|
||||||
CHECK_STATUS(res)
|
CHECK_STATUS(res)
|
||||||
|
|
||||||
length = sizeof(cmd);
|
length = sizeof(cmd);
|
||||||
res = ReadPort(reader_index, &length, cmd);
|
res = ReadPort(reader_index, &length, cmd, bSeq);
|
||||||
CHECK_STATUS(res)
|
CHECK_STATUS(res)
|
||||||
|
|
||||||
if (length < CCID_RESPONSE_HEADER_SIZE)
|
if (length < CCID_RESPONSE_HEADER_SIZE)
|
||||||
|
@ -1161,6 +1167,7 @@ RESPONSECODE CmdPowerOff(unsigned int reader_index)
|
||||||
RESPONSECODE CmdGetSlotStatus(unsigned int reader_index, unsigned char buffer[])
|
RESPONSECODE CmdGetSlotStatus(unsigned int reader_index, unsigned char buffer[])
|
||||||
{
|
{
|
||||||
unsigned char cmd[10];
|
unsigned char cmd[10];
|
||||||
|
int bSeq;
|
||||||
status_t res;
|
status_t res;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
RESPONSECODE return_value = IFD_SUCCESS;
|
RESPONSECODE return_value = IFD_SUCCESS;
|
||||||
|
@ -1247,17 +1254,18 @@ again_status:
|
||||||
InterruptRead(reader_index, 10);
|
InterruptRead(reader_index, 10);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bSeq = (*ccid_descriptor->pbSeq)++;
|
||||||
cmd[0] = 0x65; /* GetSlotStatus */
|
cmd[0] = 0x65; /* GetSlotStatus */
|
||||||
cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
|
cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
|
||||||
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
|
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
|
||||||
cmd[6] = (*ccid_descriptor->pbSeq)++;
|
cmd[6] = bSeq;
|
||||||
cmd[7] = cmd[8] = cmd[9] = 0; /* RFU */
|
cmd[7] = cmd[8] = cmd[9] = 0; /* RFU */
|
||||||
|
|
||||||
res = WritePort(reader_index, sizeof(cmd), cmd);
|
res = WritePort(reader_index, sizeof(cmd), cmd);
|
||||||
CHECK_STATUS(res)
|
CHECK_STATUS(res)
|
||||||
|
|
||||||
length = SIZE_GET_SLOT_STATUS;
|
length = SIZE_GET_SLOT_STATUS;
|
||||||
res = ReadPort(reader_index, &length, buffer);
|
res = ReadPort(reader_index, &length, buffer, bSeq);
|
||||||
CHECK_STATUS(res)
|
CHECK_STATUS(res)
|
||||||
|
|
||||||
if (length < CCID_RESPONSE_HEADER_SIZE)
|
if (length < CCID_RESPONSE_HEADER_SIZE)
|
||||||
|
@ -1546,7 +1554,7 @@ time_request_ICCD_B:
|
||||||
|
|
||||||
time_request:
|
time_request:
|
||||||
length = sizeof(cmd);
|
length = sizeof(cmd);
|
||||||
ret = ReadPort(reader_index, &length, cmd);
|
ret = ReadPort(reader_index, &length, cmd, -1);
|
||||||
|
|
||||||
/* restore the original value of read timeout */
|
/* restore the original value of read timeout */
|
||||||
ccid_descriptor -> readTimeout = old_timeout;
|
ccid_descriptor -> readTimeout = old_timeout;
|
||||||
|
@ -2304,15 +2312,17 @@ RESPONSECODE SetParameters(unsigned int reader_index, char protocol,
|
||||||
unsigned int length, unsigned char buffer[])
|
unsigned int length, unsigned char buffer[])
|
||||||
{
|
{
|
||||||
unsigned char cmd[10+length]; /* CCID + APDU buffer */
|
unsigned char cmd[10+length]; /* CCID + APDU buffer */
|
||||||
|
int bSeq;
|
||||||
_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
|
_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
|
||||||
status_t res;
|
status_t res;
|
||||||
|
|
||||||
DEBUG_COMM2("length: %d bytes", length);
|
DEBUG_COMM2("length: %d bytes", length);
|
||||||
|
|
||||||
|
bSeq = (*ccid_descriptor->pbSeq)++;
|
||||||
cmd[0] = 0x61; /* SetParameters */
|
cmd[0] = 0x61; /* SetParameters */
|
||||||
i2dw(length, cmd+1); /* APDU length */
|
i2dw(length, cmd+1); /* APDU length */
|
||||||
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
|
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
|
||||||
cmd[6] = (*ccid_descriptor->pbSeq)++;
|
cmd[6] = bSeq;
|
||||||
cmd[7] = protocol; /* bProtocolNum */
|
cmd[7] = protocol; /* bProtocolNum */
|
||||||
cmd[8] = cmd[9] = 0; /* RFU */
|
cmd[8] = cmd[9] = 0; /* RFU */
|
||||||
|
|
||||||
|
@ -2322,7 +2332,7 @@ RESPONSECODE SetParameters(unsigned int reader_index, char protocol,
|
||||||
CHECK_STATUS(res)
|
CHECK_STATUS(res)
|
||||||
|
|
||||||
length = sizeof(cmd);
|
length = sizeof(cmd);
|
||||||
res = ReadPort(reader_index, &length, cmd);
|
res = ReadPort(reader_index, &length, cmd, bSeq);
|
||||||
CHECK_STATUS(res)
|
CHECK_STATUS(res)
|
||||||
|
|
||||||
if (length < CCID_RESPONSE_HEADER_SIZE)
|
if (length < CCID_RESPONSE_HEADER_SIZE)
|
||||||
|
|
61
src/debug.h
61
src/debug.h
|
@ -73,53 +73,46 @@ extern int LogLevel;
|
||||||
#define DEBUG_COMM3(fmt, data1, data2) os_log_info(OS_LOG_DEFAULT, fmt, data1, data2)
|
#define DEBUG_COMM3(fmt, data1, data2) os_log_info(OS_LOG_DEFAULT, fmt, data1, data2)
|
||||||
#define DEBUG_COMM4(fmt, data1, data2, data3) os_log_info(OS_LOG_DEFAULT, fmt, data1, data2, data3)
|
#define DEBUG_COMM4(fmt, data1, data2, data3) os_log_info(OS_LOG_DEFAULT, fmt, data1, data2, data3)
|
||||||
|
|
||||||
#define DEBUG_INFO_XXD(msg, buffer, size) if (LogLevel & DEBUG_LEVEL_INFO) log_xxd(PCSC_LOG_INFO, msg, buffer, size)
|
#define DEBUG_INFO_XXD(msg, buffer, size) do { if (LogLevel & DEBUG_LEVEL_INFO) log_xxd(PCSC_LOG_INFO, msg, buffer, size); } while (0)
|
||||||
#define DEBUG_XXD(msg, buffer, size) if (LogLevel & DEBUG_LEVEL_COMM) log_xxd(PCSC_LOG_DEBUG, msg, buffer, size)
|
#define DEBUG_XXD(msg, buffer, size) do { if (LogLevel & DEBUG_LEVEL_COMM) log_xxd(PCSC_LOG_DEBUG, msg, buffer, size); } while (0)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#define TO_PCSCD_LOG(fmt, CCID_LEVEL, PCSCD_LEVEL) do { if (LogLevel & DEBUG_LEVEL_ ## CCID_LEVEL) Log1(PCSC_LOG_ ## PCSCD_LEVEL, fmt); } while (0)
|
||||||
|
#define TO_PCSCD_LOG2(fmt, data, CCID_LEVEL, PCSCD_LEVEL) do { if (LogLevel & DEBUG_LEVEL_ ## CCID_LEVEL) Log2(PCSC_LOG_ ## PCSCD_LEVEL, fmt, data); } while (0)
|
||||||
|
#define TO_PCSCD_LOG3(fmt, data1, data2, CCID_LEVEL, PCSCD_LEVEL) do { if (LogLevel & DEBUG_LEVEL_ ## CCID_LEVEL) Log3(PCSC_LOG_ ## PCSCD_LEVEL, fmt, data1, data2); } while (0)
|
||||||
|
#define TO_PCSCD_LOG4(fmt, data1, data2, data3, CCID_LEVEL, PCSCD_LEVEL) do { if (LogLevel & DEBUG_LEVEL_ ## CCID_LEVEL) Log4(PCSC_LOG_ ## PCSCD_LEVEL, fmt, data1, data2, data3); } while (0)
|
||||||
|
#define TO_PCSCD_LOG5(fmt, data1, data2, data3, data4, CCID_LEVEL, PCSCD_LEVEL) do { if (LogLevel & DEBUG_LEVEL_ ## CCID_LEVEL) Log5(PCSC_LOG_ ## PCSCD_LEVEL, fmt, data1, data2, data3, data4); } while (0)
|
||||||
|
|
||||||
/* DEBUG_CRITICAL */
|
/* DEBUG_CRITICAL */
|
||||||
#define DEBUG_CRITICAL(fmt) if (LogLevel & DEBUG_LEVEL_CRITICAL) Log1(PCSC_LOG_CRITICAL, fmt)
|
#define DEBUG_CRITICAL(fmt) TO_PCSCD_LOG(fmt, CRITICAL, CRITICAL)
|
||||||
|
#define DEBUG_CRITICAL2(fmt, data) TO_PCSCD_LOG2(fmt, data, CRITICAL, CRITICAL)
|
||||||
#define DEBUG_CRITICAL2(fmt, data) if (LogLevel & DEBUG_LEVEL_CRITICAL) Log2(PCSC_LOG_CRITICAL, fmt, data)
|
#define DEBUG_CRITICAL3(fmt, data1, data2) TO_PCSCD_LOG3(fmt, data1, data2, CRITICAL, CRITICAL)
|
||||||
|
#define DEBUG_CRITICAL4(fmt, data1, data2, data3) TO_PCSCD_LOG4(fmt, data1, data2, data3, CRITICAL, CRITICAL)
|
||||||
#define DEBUG_CRITICAL3(fmt, data1, data2) if (LogLevel & DEBUG_LEVEL_CRITICAL) Log3(PCSC_LOG_CRITICAL, fmt, data1, data2)
|
#define DEBUG_CRITICAL5(fmt, data1, data2, data3, data4) TO_PCSCD_LOG5(fmt, data1, data2, data3, data4, CRITICAL, CRITICAL)
|
||||||
|
|
||||||
#define DEBUG_CRITICAL4(fmt, data1, data2, data3) if (LogLevel & DEBUG_LEVEL_CRITICAL) Log4(PCSC_LOG_CRITICAL, fmt, data1, data2, data3)
|
|
||||||
|
|
||||||
#define DEBUG_CRITICAL5(fmt, data1, data2, data3, data4) if (LogLevel & DEBUG_LEVEL_CRITICAL) Log5(PCSC_LOG_CRITICAL, fmt, data1, data2, data3, data4)
|
|
||||||
|
|
||||||
/* DEBUG_INFO */
|
/* DEBUG_INFO */
|
||||||
#define DEBUG_INFO1(fmt) if (LogLevel & DEBUG_LEVEL_INFO) Log1(PCSC_LOG_INFO, fmt)
|
#define DEBUG_INFO1(fmt) TO_PCSCD_LOG(fmt, INFO, INFO)
|
||||||
|
#define DEBUG_INFO2(fmt, data) TO_PCSCD_LOG2(fmt, data, INFO, INFO)
|
||||||
|
#define DEBUG_INFO3(fmt, data1, data2) TO_PCSCD_LOG3(fmt, data1, data2, INFO, INFO)
|
||||||
|
#define DEBUG_INFO4(fmt, data1, data2, data3) TO_PCSCD_LOG4(fmt, data1, data2, data3, INFO, INFO)
|
||||||
|
#define DEBUG_INFO5(fmt, data1, data2, data3, data4) TO_PCSCD_LOG5(fmt, data1, data2, data3, data4, INFO, INFO)
|
||||||
|
|
||||||
#define DEBUG_INFO2(fmt, data) if (LogLevel & DEBUG_LEVEL_INFO) Log2(PCSC_LOG_INFO, fmt, data)
|
#define DEBUG_INFO_XXD(msg, buffer, size) do { if (LogLevel & DEBUG_LEVEL_INFO) log_xxd(PCSC_LOG_INFO, msg, buffer, size); } while (0)
|
||||||
|
|
||||||
#define DEBUG_INFO3(fmt, data1, data2) if (LogLevel & DEBUG_LEVEL_INFO) Log3(PCSC_LOG_INFO, fmt, data1, data2)
|
|
||||||
|
|
||||||
#define DEBUG_INFO4(fmt, data1, data2, data3) if (LogLevel & DEBUG_LEVEL_INFO) Log4(PCSC_LOG_INFO, fmt, data1, data2, data3)
|
|
||||||
|
|
||||||
#define DEBUG_INFO5(fmt, data1, data2, data3, data4) if (LogLevel & DEBUG_LEVEL_INFO) Log5(PCSC_LOG_INFO, fmt, data1, data2, data3, data4)
|
|
||||||
|
|
||||||
#define DEBUG_INFO_XXD(msg, buffer, size) if (LogLevel & DEBUG_LEVEL_INFO) LogXxd(PCSC_LOG_INFO, msg, buffer, size)
|
|
||||||
|
|
||||||
/* DEBUG_PERIODIC */
|
/* DEBUG_PERIODIC */
|
||||||
#define DEBUG_PERIODIC(fmt) if (LogLevel & DEBUG_LEVEL_PERIODIC) Log1(PCSC_LOG_DEBUG, fmt)
|
#define DEBUG_PERIODIC(fmt) TO_PCSCD_LOG(fmt, PERIODIC, DEBUG)
|
||||||
|
#define DEBUG_PERIODIC2(fmt, data) TO_PCSCD_LOG2(fmt, data, PERIODIC, DEBUG)
|
||||||
#define DEBUG_PERIODIC2(fmt, data) if (LogLevel & DEBUG_LEVEL_PERIODIC) Log2(PCSC_LOG_DEBUG, fmt, data)
|
#define DEBUG_PERIODIC3(fmt, data1, data2) TO_PCSCD_LOG3(fmt, data1, data2, PERIODIC, DEBUG)
|
||||||
|
|
||||||
#define DEBUG_PERIODIC3(fmt, data1, data2) if (LogLevel & DEBUG_LEVEL_PERIODIC) Log3(PCSC_LOG_DEBUG, fmt, data1, data2)
|
|
||||||
|
|
||||||
/* DEBUG_COMM */
|
/* DEBUG_COMM */
|
||||||
#define DEBUG_COMM(fmt) if (LogLevel & DEBUG_LEVEL_COMM) Log1(PCSC_LOG_DEBUG, fmt)
|
#define DEBUG_COMM(fmt) TO_PCSCD_LOG(fmt, COMM, DEBUG)
|
||||||
|
#define DEBUG_COMM2(fmt, data) TO_PCSCD_LOG2(fmt, data, COMM, DEBUG)
|
||||||
#define DEBUG_COMM2(fmt, data) if (LogLevel & DEBUG_LEVEL_COMM) Log2(PCSC_LOG_DEBUG, fmt, data)
|
#define DEBUG_COMM3(fmt, data1, data2) TO_PCSCD_LOG3(fmt, data1, data2, COMM, DEBUG)
|
||||||
|
#define DEBUG_COMM4(fmt, data1, data2, data3) TO_PCSCD_LOG4(fmt, data1, data2, data3, COMM, DEBUG)
|
||||||
#define DEBUG_COMM3(fmt, data1, data2) if (LogLevel & DEBUG_LEVEL_COMM) Log3(PCSC_LOG_DEBUG, fmt, data1, data2)
|
|
||||||
|
|
||||||
#define DEBUG_COMM4(fmt, data1, data2, data3) if (LogLevel & DEBUG_LEVEL_COMM) Log4(PCSC_LOG_DEBUG, fmt, data1, data2, data3)
|
|
||||||
|
|
||||||
/* DEBUG_XXD */
|
/* DEBUG_XXD */
|
||||||
#define DEBUG_XXD(msg, buffer, size) if (LogLevel & DEBUG_LEVEL_COMM) LogXxd(PCSC_LOG_DEBUG, msg, buffer, size)
|
#define DEBUG_XXD(msg, buffer, size) do { if (LogLevel & DEBUG_LEVEL_COMM) log_xxd(PCSC_LOG_DEBUG, msg, buffer, size); } while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ typedef enum {
|
||||||
#define ClosePort CloseSerial
|
#define ClosePort CloseSerial
|
||||||
#define ReadPort ReadSerial
|
#define ReadPort ReadSerial
|
||||||
#define WritePort WriteSerial
|
#define WritePort WriteSerial
|
||||||
|
#define DisconnectPort DisconnectSerial
|
||||||
#include "ccid_serial.h"
|
#include "ccid_serial.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -105,6 +106,7 @@ typedef enum {
|
||||||
#define ClosePort CloseUSB
|
#define ClosePort CloseUSB
|
||||||
#define ReadPort ReadUSB
|
#define ReadPort ReadUSB
|
||||||
#define WritePort WriteUSB
|
#define WritePort WriteUSB
|
||||||
|
#define DisconnectPort DisconnectUSB
|
||||||
#include "ccid_usb.h"
|
#include "ccid_usb.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -490,8 +490,12 @@ EXTERNAL RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag,
|
||||||
case TAG_IFD_SLOT_THREAD_SAFE:
|
case TAG_IFD_SLOT_THREAD_SAFE:
|
||||||
if (*Length >= 1)
|
if (*Length >= 1)
|
||||||
{
|
{
|
||||||
|
_ccid_descriptor *ccid_desc = get_ccid_descriptor(reader_index);
|
||||||
*Length = 1;
|
*Length = 1;
|
||||||
*Value = 0; /* Can NOT talk to multiple slots at the same time */
|
if (ccid_desc->bMaxSlotIndex +1 == ccid_desc->bMaxCCIDBusySlots)
|
||||||
|
*Value = 1; /* all slots can be used simultanesously */
|
||||||
|
else
|
||||||
|
*Value = 0; /* Can NOT talk to multiple slots at the same time */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return_value = IFD_ERROR_INSUFFICIENT_BUFFER;
|
return_value = IFD_ERROR_INSUFFICIENT_BUFFER;
|
||||||
|
@ -602,6 +606,13 @@ EXTERNAL RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag,
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TAG_IFD_DEVICE_REMOVED
|
||||||
|
case TAG_IFD_DEVICE_REMOVED:
|
||||||
|
if (Value && (1 == *Length))
|
||||||
|
Value[0] = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case SCARD_ATTR_VENDOR_IFD_SERIAL_NO:
|
case SCARD_ATTR_VENDOR_IFD_SERIAL_NO:
|
||||||
{
|
{
|
||||||
_ccid_descriptor *ccid_desc;
|
_ccid_descriptor *ccid_desc;
|
||||||
|
@ -661,6 +672,7 @@ EXTERNAL RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag,
|
||||||
* IFD_ERROR_VALUE_READ_ONLY
|
* IFD_ERROR_VALUE_READ_ONLY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
RESPONSECODE return_value = IFD_SUCCESS;
|
||||||
(void)Length;
|
(void)Length;
|
||||||
(void)Value;
|
(void)Value;
|
||||||
|
|
||||||
|
@ -672,7 +684,20 @@ EXTERNAL RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag,
|
||||||
DEBUG_INFO4("tag: 0x" DWORD_X ", %s (lun: " DWORD_X ")", Tag,
|
DEBUG_INFO4("tag: 0x" DWORD_X ", %s (lun: " DWORD_X ")", Tag,
|
||||||
CcidSlots[reader_index].readerName, Lun);
|
CcidSlots[reader_index].readerName, Lun);
|
||||||
|
|
||||||
return IFD_NOT_SUPPORTED;
|
switch (Tag)
|
||||||
|
{
|
||||||
|
#ifdef TAG_IFD_DEVICE_REMOVED
|
||||||
|
case TAG_IFD_DEVICE_REMOVED:
|
||||||
|
if ((1 == Length) && (Value != NULL) && (Value[0] != 0))
|
||||||
|
DisconnectPort(reader_index);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return_value = IFD_ERROR_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
return return_value;
|
||||||
} /* IFDHSetCapabilities */
|
} /* IFDHSetCapabilities */
|
||||||
|
|
||||||
|
|
||||||
|
@ -791,10 +816,7 @@ EXTERNAL RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol,
|
||||||
/* Do not send CCID command SetParameters or PPS to the CCID
|
/* Do not send CCID command SetParameters or PPS to the CCID
|
||||||
* The CCID will do this himself */
|
* The CCID will do this himself */
|
||||||
if (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_PROP)
|
if (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_PROP)
|
||||||
{
|
|
||||||
DEBUG_COMM2("Timeout: %d ms", ccid_desc->readTimeout);
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
|
||||||
|
|
||||||
/* PTS1? */
|
/* PTS1? */
|
||||||
if (Flags & IFD_NEGOTIATE_PTS1)
|
if (Flags & IFD_NEGOTIATE_PTS1)
|
||||||
|
@ -967,6 +989,7 @@ EXTERNAL RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol,
|
||||||
&& (atr.ib[1][ATR_INTERFACE_BYTE_TA].value & 0x10))
|
&& (atr.ib[1][ATR_INTERFACE_BYTE_TA].value & 0x10))
|
||||||
return IFD_COMMUNICATION_ERROR;
|
return IFD_COMMUNICATION_ERROR;
|
||||||
|
|
||||||
|
end:
|
||||||
/* T=1 */
|
/* T=1 */
|
||||||
if (SCARD_PROTOCOL_T1 == Protocol)
|
if (SCARD_PROTOCOL_T1 == Protocol)
|
||||||
{
|
{
|
||||||
|
@ -1046,9 +1069,14 @@ EXTERNAL RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol,
|
||||||
|
|
||||||
DEBUG_COMM2("Timeout: %d ms", ccid_desc->readTimeout);
|
DEBUG_COMM2("Timeout: %d ms", ccid_desc->readTimeout);
|
||||||
|
|
||||||
ret = SetParameters(reader_index, 1, sizeof(param), param);
|
if (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_PROP)
|
||||||
if (IFD_SUCCESS != ret)
|
DEBUG_COMM("Skip SetParameters");
|
||||||
return ret;
|
else
|
||||||
|
{
|
||||||
|
ret = SetParameters(reader_index, 1, sizeof(param), param);
|
||||||
|
if (IFD_SUCCESS != ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* T=0 */
|
/* T=0 */
|
||||||
|
@ -1085,14 +1113,18 @@ EXTERNAL RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol,
|
||||||
ccid_desc->readTimeout = T0_card_timeout(f, d, param[2] /* TC1 */,
|
ccid_desc->readTimeout = T0_card_timeout(f, d, param[2] /* TC1 */,
|
||||||
param[3] /* TC2 */, ccid_desc->dwDefaultClock);
|
param[3] /* TC2 */, ccid_desc->dwDefaultClock);
|
||||||
|
|
||||||
DEBUG_COMM2("Communication timeout: %d ms", ccid_desc->readTimeout);
|
DEBUG_COMM2("Timeout: %d ms", ccid_desc->readTimeout);
|
||||||
|
|
||||||
ret = SetParameters(reader_index, 0, sizeof(param), param);
|
if (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_PROP)
|
||||||
if (IFD_SUCCESS != ret)
|
DEBUG_COMM("Skip SetParameters");
|
||||||
return ret;
|
else
|
||||||
|
{
|
||||||
|
ret = SetParameters(reader_index, 0, sizeof(param), param);
|
||||||
|
if (IFD_SUCCESS != ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
|
||||||
/* set IFSC & IFSD in T=1 */
|
/* set IFSC & IFSD in T=1 */
|
||||||
if ((SCARD_PROTOCOL_T1 == Protocol)
|
if ((SCARD_PROTOCOL_T1 == Protocol)
|
||||||
&& (CCID_CLASS_TPDU == (ccid_desc->dwFeatures & CCID_CLASS_EXCHANGE_MASK)))
|
&& (CCID_CLASS_TPDU == (ccid_desc->dwFeatures & CCID_CLASS_EXCHANGE_MASK)))
|
||||||
|
@ -1195,6 +1227,9 @@ EXTERNAL RESPONSECODE IFDHPowerICC(DWORD Lun, DWORD Action,
|
||||||
CcidSlots[reader_index].bPowerFlags |= MASK_POWERFLAGS_PDWN;
|
CcidSlots[reader_index].bPowerFlags |= MASK_POWERFLAGS_PDWN;
|
||||||
|
|
||||||
/* send the command */
|
/* send the command */
|
||||||
|
return_value = CmdPowerOff(reader_index);
|
||||||
|
if (IFD_NO_SUCH_DEVICE == return_value)
|
||||||
|
goto end;
|
||||||
if (IFD_SUCCESS != CmdPowerOff(reader_index))
|
if (IFD_SUCCESS != CmdPowerOff(reader_index))
|
||||||
{
|
{
|
||||||
DEBUG_CRITICAL("PowerDown failed");
|
DEBUG_CRITICAL("PowerDown failed");
|
||||||
|
@ -1469,6 +1504,10 @@ EXTERNAL RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode,
|
||||||
allowed = TRUE;
|
allowed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* allow APDU exchange with this reader without a card in the field */
|
||||||
|
if (HID_OMNIKEY_5427CK == readerID)
|
||||||
|
allowed = TRUE;
|
||||||
|
|
||||||
if (!allowed)
|
if (!allowed)
|
||||||
{
|
{
|
||||||
DEBUG_INFO1("ifd exchange (Escape command) not allowed");
|
DEBUG_INFO1("ifd exchange (Escape command) not allowed");
|
||||||
|
@ -1915,6 +1954,12 @@ EXTERNAL RESPONSECODE IFDHICCPresence(DWORD Lun)
|
||||||
/* set back the old LogLevel */
|
/* set back the old LogLevel */
|
||||||
LogLevel = oldLogLevel;
|
LogLevel = oldLogLevel;
|
||||||
|
|
||||||
|
if (IFD_NO_SUCH_DEVICE == return_value)
|
||||||
|
{
|
||||||
|
return_value = IFD_ICC_NOT_PRESENT;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (return_value != IFD_SUCCESS)
|
if (return_value != IFD_SUCCESS)
|
||||||
return return_value;
|
return return_value;
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,8 @@ int t1_transceive(t1_state_t * t1, unsigned int dad,
|
||||||
{
|
{
|
||||||
ct_buf_t sbuf, rbuf, tbuf;
|
ct_buf_t sbuf, rbuf, tbuf;
|
||||||
unsigned char sdata[T1_BUFFER_SIZE], sblk[5];
|
unsigned char sdata[T1_BUFFER_SIZE], sblk[5];
|
||||||
unsigned int slen, retries, resyncs;
|
unsigned int slen, resyncs;
|
||||||
|
int retries;
|
||||||
size_t last_send = 0;
|
size_t last_send = 0;
|
||||||
|
|
||||||
if (snd_len == 0)
|
if (snd_len == 0)
|
||||||
|
@ -745,7 +746,7 @@ int t1_negotiate_ifsd(t1_state_t * t1, unsigned int dad, int ifsd)
|
||||||
ct_buf_t sbuf;
|
ct_buf_t sbuf;
|
||||||
unsigned char sdata[T1_BUFFER_SIZE];
|
unsigned char sdata[T1_BUFFER_SIZE];
|
||||||
unsigned int slen;
|
unsigned int slen;
|
||||||
unsigned int retries;
|
int retries;
|
||||||
size_t snd_len;
|
size_t snd_len;
|
||||||
int n;
|
int n;
|
||||||
unsigned char snd_buf[1];
|
unsigned char snd_buf[1];
|
||||||
|
@ -764,14 +765,14 @@ int t1_negotiate_ifsd(t1_state_t * t1, unsigned int dad, int ifsd)
|
||||||
/* Build the block */
|
/* Build the block */
|
||||||
slen = t1_build(t1, sdata, 0, T1_S_BLOCK | T1_S_IFS, &sbuf, NULL);
|
slen = t1_build(t1, sdata, 0, T1_S_BLOCK | T1_S_IFS, &sbuf, NULL);
|
||||||
|
|
||||||
/* Send the block */
|
|
||||||
n = t1_xcv(t1, sdata, slen, sizeof(sdata));
|
|
||||||
|
|
||||||
retries--;
|
retries--;
|
||||||
/* ISO 7816-3 Rule 7.4.2 */
|
/* ISO 7816-3 Rule 7.4.2 */
|
||||||
if (retries <= 0)
|
if (retries < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
/* Send the block */
|
||||||
|
n = t1_xcv(t1, sdata, slen, sizeof(sdata));
|
||||||
|
|
||||||
if (-1 == n)
|
if (-1 == n)
|
||||||
{
|
{
|
||||||
DEBUG_CRITICAL("fatal: transmit/receive failed");
|
DEBUG_CRITICAL("fatal: transmit/receive failed");
|
||||||
|
|
|
@ -28,13 +28,14 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
int ReaderIndex[CCID_DRIVER_MAX_READERS];
|
int ReaderIndex[CCID_DRIVER_MAX_READERS];
|
||||||
|
#define FREE_ENTRY -42
|
||||||
|
|
||||||
void InitReaderIndex(void)
|
void InitReaderIndex(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<CCID_DRIVER_MAX_READERS; i++)
|
for (i=0; i<CCID_DRIVER_MAX_READERS; i++)
|
||||||
ReaderIndex[i] = -1;
|
ReaderIndex[i] = FREE_ENTRY;
|
||||||
} /* InitReaderIndex */
|
} /* InitReaderIndex */
|
||||||
|
|
||||||
int GetNewReaderIndex(const int Lun)
|
int GetNewReaderIndex(const int Lun)
|
||||||
|
@ -53,7 +54,7 @@ int GetNewReaderIndex(const int Lun)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<CCID_DRIVER_MAX_READERS; i++)
|
for (i=0; i<CCID_DRIVER_MAX_READERS; i++)
|
||||||
if (-1 == ReaderIndex[i])
|
if (FREE_ENTRY == ReaderIndex[i])
|
||||||
{
|
{
|
||||||
ReaderIndex[i] = Lun;
|
ReaderIndex[i] = Lun;
|
||||||
return i;
|
return i;
|
||||||
|
@ -77,7 +78,7 @@ int LunToReaderIndex(const int Lun)
|
||||||
|
|
||||||
void ReleaseReaderIndex(const int index)
|
void ReleaseReaderIndex(const int index)
|
||||||
{
|
{
|
||||||
ReaderIndex[index] = -1;
|
ReaderIndex[index] = FREE_ENTRY;
|
||||||
} /* ReleaseReaderIndex */
|
} /* ReleaseReaderIndex */
|
||||||
|
|
||||||
/* Read a non aligned 16-bit integer */
|
/* Read a non aligned 16-bit integer */
|
||||||
|
|
2
ylwrap
2
ylwrap
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
scriptversion=2018-03-07.03; # UTC
|
scriptversion=2018-03-07.03; # UTC
|
||||||
|
|
||||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in New Issue