<div dir="auto"><div>Hello,<div dir="auto"><br></div><div dir="auto">Please generate a pcscd trace as described at <a href="http://pcsclite.alioth.debian.org/pcsclite.html#support">http://pcsclite.alioth.debian.org/pcsclite.html#support</a></div><div dir="auto"><br></div><div dir="auto">bye</div><div dir="auto"><br><div data-smartmail="gmail_signature" dir="auto">Dr. Ludovic Rousseau</div></div><br><div class="gmail_extra"><br><div class="gmail_quote">Le 21 juil. 2017 13:47, "Thomas Bajer" <<a href="mailto:thomas.bajer@physec.de">thomas.bajer@physec.de</a>> a écrit :<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
<br>
<br>
<br>
I would like to report an error, which occurs, when using PCSC-lite for<br>
smartcard detection in C. It causes the smartcard to remain undetected,<br>
when the reader is disconnected. The current workaround is to restart<br>
the PCSC deamon at the beginning.<br>
<br>
In my application the removal of the reader is unavoidable, since I am<br>
using a USB token, which acts as a combination of a reader and a smartcard.<br>
<br>
<br>
<br>
Please have a look at the attached minimal example code. The program<br>
checks, whether a reader an a card are available, then connects to the<br>
smartcard. Afterwards, the smartcard is diconnected and the program<br>
waits until the smartcard is no longer physically connected. This<br>
process is being looped until the programm is aborted.<br>
<br>
<br>
<br>
The code was linked with the newest stable release, 1.8.22-1.<br>
<br>
The code is compiled and linked on a FreeBSD system running FreeBSD 10.3<br>
(AMD64), the executable is then copied to a pfsense Box which also runs<br>
FreeBSD 10.3 with the same pcscd version.<br>
<br>
<br>
<br>
It would be great if a developer could look at this and commit a fix for<br>
this message.<br>
<br>
<br>
<br>
Below is the exampleReconnect.c example and the build command. Feel free<br>
to play around with it and to make use of the defines at the beginning<br>
of the code<br>
<br>
<br>
<br>
Regards,<br>
<br>
Thomas Bajer<br>
<br>
<br>
<br>
/*<br>
<br>
* exampleReconnect.c<br>
<br>
*<br>
<br>
* Created on: 20.07.2017<br>
<br>
* Author: T. Bajer<br>
<br>
*/<br>
<br>
<br>
<br>
<br>
<br>
#include <stdio.h><br>
<br>
#include <stdlib.h><br>
<br>
#include <unistd.h><br>
<br>
//#include <usb.h><br>
<br>
#include <errno.h><br>
<br>
#include <stdint.h><br>
<br>
#ifdef __APPLE__<br>
<br>
#include <PCSC/winscard.h><br>
<br>
#include <PCSC/wintypes.h><br>
<br>
#else<br>
<br>
#include <winscard.h><br>
<br>
#endif<br>
<br>
<br>
<br>
<br>
<br>
/*<br>
##############################<wbr>##############################<wbr>##############################<wbr>##<br>
<br>
* #### BUILD COMMAND:<br>
####<br>
<br>
* #### gcc -o example exampleReconnect.c -I/usr/local/include/PCSC<br>
-lpcsclite -lusb -Wall ####<br>
<br>
*<br>
##############################<wbr>##############################<wbr>##############################<wbr>##<br>
*/<br>
<br>
<br>
<br>
/* Uncomment me for more details */<br>
<br>
//#define SC_DEBUG<br>
<br>
<br>
<br>
/* Uncomment me to make it work */<br>
<br>
//#define HOTFIX<br>
<br>
<br>
<br>
<br>
<br>
/*<br>
<br>
* Prototypes<br>
<br>
*/<br>
<br>
int connectToSmartcard( SCARDCONTEXT *hContext,<br>
<br>
SCARDHANDLE *hCard,<br>
<br>
LPTSTR *mszReaders);<br>
<br>
<br>
<br>
void disconnectSmartcard( SCARDCONTEXT *hContext,<br>
<br>
SCARDHANDLE *hCard,<br>
<br>
LPTSTR *mszReaders);<br>
<br>
<br>
<br>
void waitForSmartcardConnect();<br>
<br>
<br>
<br>
void waitForSmartcardDisconnect();<br>
<br>
<br>
<br>
<br>
<br>
/*<br>
<br>
* MAIN function<br>
<br>
*/<br>
<br>
int main(int argc, char **argv)<br>
<br>
{<br>
<br>
SCARDCONTEXT hContext;<br>
<br>
SCARDHANDLE hCard;<br>
<br>
LPTSTR mszReaders;<br>
<br>
<br>
<br>
printf("Smartcard detection started.\n");<br>
<br>
for(;;)<br>
<br>
{<br>
<br>
printf("Waiting for smartcard connect...\n");<br>
<br>
<br>
<br>
#ifdef HOTFIX<br>
<br>
system("service pcscd restart");<br>
<br>
#endif<br>
<br>
waitForSmartcardConnect();<br>
<br>
printf("Smartcard found.\n");<br>
<br>
<br>
<br>
printf("Connecting to smartcard...\n");<br>
<br>
if(connectToSmartcard(&<wbr>hContext, &hCard, &mszReaders) == 0)<br>
<br>
{<br>
<br>
printf("Connecting successful!\n");<br>
<br>
<br>
<br>
/*<br>
<br>
* Do SC stuff here<br>
<br>
*/<br>
<br>
<br>
<br>
printf("Disconnecting...\n");<br>
<br>
disconnectSmartcard(&hContext, &hCard, &mszReaders);<br>
<br>
printf("Disconnected!\n");<br>
<br>
}<br>
<br>
else<br>
<br>
{<br>
<br>
printf("CONNECT FAILED!\n");<br>
<br>
}<br>
<br>
<br>
<br>
printf("Waiting for smartcard disconnect...\n");<br>
<br>
waitForSmartcardDisconnect();<br>
<br>
printf("Smartcard lost!\n");<br>
<br>
}<br>
<br>
<br>
<br>
return 0;<br>
<br>
}<br>
<br>
<br>
<br>
<br>
<br>
/*<br>
<br>
* Implementations<br>
<br>
*/<br>
<br>
<br>
<br>
int connectToSmartcard( SCARDCONTEXT *hContext,<br>
<br>
SCARDHANDLE *hCard,<br>
<br>
LPTSTR *mszReaders)<br>
<br>
{<br>
<br>
LONG rv = 0;<br>
<br>
<br>
<br>
DWORD dwReaders, dwActiveProtocol ;<br>
<br>
<br>
<br>
// Init context<br>
<br>
printf("Establish context\n");<br>
<br>
rv = SCardEstablishContext( SCARD_SCOPE_SYSTEM,<br>
<br>
NULL,<br>
<br>
NULL, hContext);<br>
<br>
if (SCARD_S_SUCCESS != rv)<br>
<br>
{<br>
<br>
return -1;<br>
<br>
}<br>
<br>
<br>
<br>
// Get available smartcard readers<br>
<br>
#ifdef SCARD_AUTOALLOCATE<br>
<br>
dwReaders = SCARD_AUTOALLOCATE;<br>
<br>
printf("List readers\n");<br>
<br>
rv = SCardListReaders( *hContext,<br>
<br>
NULL,<br>
<br>
(LPTSTR)mszReaders,<br>
<br>
&dwReaders);<br>
<br>
<br>
<br>
if (SCARD_S_SUCCESS != rv)<br>
<br>
{<br>
<br>
SCardReleaseContext(*hContext)<wbr>;<br>
<br>
return -1;<br>
<br>
}<br>
<br>
<br>
<br>
#else<br>
<br>
printf("List readers\n");<br>
<br>
rv = SCardListReaders( *hContext,<br>
<br>
NULL,<br>
<br>
NULL,<br>
<br>
&dwReaders);<br>
<br>
if (SCARD_S_SUCCESS != rv)<br>
<br>
{<br>
<br>
SCardReleaseContext(*hContext)<wbr>;<br>
<br>
return -1;<br>
<br>
}<br>
<br>
printf("Allocate readers\n");<br>
<br>
mszReaders = calloc(dwReaders, sizeof(char));<br>
<br>
rv = SCardListReaders( *hContext,<br>
<br>
NULL,<br>
<br>
*mszReaders,<br>
<br>
&dwReaders );<br>
<br>
if(SCARD_S_SUCCESS != rv)<br>
<br>
{<br>
<br>
SCardFreeMemory( *hContext, mszReaders );<br>
<br>
SCardReleaseContext( *hContext );<br>
<br>
return -1;<br>
<br>
}<br>
<br>
<br>
<br>
#endif<br>
<br>
<br>
<br>
printf( "Connect to card\n" );<br>
<br>
// Connect to smartcard<br>
<br>
rv = SCardConnect( *hContext,<br>
<br>
*mszReaders,<br>
<br>
SCARD_SHARE_SHARED,<br>
<br>
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,<br>
<br>
hCard,<br>
<br>
&dwActiveProtocol );<br>
<br>
if (SCARD_S_SUCCESS != rv)<br>
<br>
{<br>
<br>
SCardFreeMemory( *hContext, *mszReaders );<br>
<br>
SCardReleaseContext( *hContext );<br>
<br>
return -1;<br>
<br>
}<br>
<br>
<br>
<br>
printf( "Smartcard connected!\n" );<br>
<br>
return 0;<br>
<br>
}<br>
<br>
<br>
<br>
void disconnectSmartcard( SCARDCONTEXT *hContext,<br>
<br>
SCARDHANDLE *hCard,<br>
<br>
LPTSTR *mszReaders)<br>
<br>
{<br>
<br>
printf("Disconnect card...\n");<br>
<br>
SCardDisconnect( *hCard, SCARD_LEAVE_CARD );<br>
<br>
<br>
<br>
printf("Free reader...\n");<br>
<br>
#ifdef SCARD_AUTOALLOCATE<br>
<br>
<br>
<br>
SCardFreeMemory( *hContext, *mszReaders );<br>
<br>
<br>
<br>
#else<br>
<br>
free( *mszReaders );<br>
<br>
#endif<br>
<br>
<br>
<br>
printf( "Release context...\n" );<br>
<br>
SCardReleaseContext( *hContext );<br>
<br>
}<br>
<br>
<br>
<br>
<br>
<br>
int checkSmartcard( SCARDCONTEXT *hContext,<br>
<br>
SCARDHANDLE *hCard,<br>
<br>
LPTSTR *mszReaders)<br>
<br>
{<br>
<br>
LONG rv = 0;<br>
<br>
<br>
<br>
DWORD dwReaders, dwActiveProtocol;<br>
<br>
<br>
<br>
// Init context<br>
<br>
#ifdef SC_DEBUG<br>
<br>
printf("Establishing SC context...\n");<br>
<br>
#endif<br>
<br>
rv = SCardEstablishContext( SCARD_SCOPE_SYSTEM,<br>
<br>
NULL,<br>
<br>
NULL,<br>
<br>
hContext);<br>
<br>
if (SCARD_S_SUCCESS != rv)<br>
<br>
{<br>
<br>
#ifdef SC_DEBUG<br>
<br>
printf("ERROR: Establishing SC context!\n");<br>
<br>
<br>
<br>
#endif<br>
<br>
}<br>
<br>
<br>
<br>
// Get available smartcard readers<br>
<br>
#ifdef SCARD_AUTOALLOCATE<br>
<br>
if (SCARD_S_SUCCESS == rv)<br>
<br>
{<br>
<br>
dwReaders = SCARD_AUTOALLOCATE;<br>
<br>
<br>
<br>
#ifdef SC_DEBUG<br>
<br>
printf("Listing SC readers...\n");<br>
<br>
#endif<br>
<br>
<br>
<br>
rv = SCardListReaders( *hContext,<br>
<br>
NULL,<br>
<br>
(LPTSTR)mszReaders,<br>
<br>
&dwReaders );<br>
<br>
if (SCARD_S_SUCCESS != rv)<br>
<br>
{<br>
<br>
#ifdef SC_DEBUG<br>
<br>
printf("ERROR: Listing SC readers!\n");<br>
<br>
#endif<br>
<br>
/* Max: this has to be given by value, not by pointer! (even if it<br>
doesn't make sense..) */<br>
<br>
SCardReleaseContext(*hContext)<wbr>;<br>
<br>
}<br>
<br>
}<br>
<br>
#else<br>
<br>
if (SCARD_S_SUCCESS == rv)<br>
<br>
{<br>
<br>
#ifdef SC_DEBUG<br>
<br>
printf("Listing SC readers...\n");<br>
<br>
#endif<br>
<br>
rv = SCardListReaders( *hContext,<br>
<br>
NULL,<br>
<br>
NULL,<br>
<br>
&dwReaders);<br>
<br>
if (SCARD_S_SUCCESS != rv)<br>
<br>
{<br>
<br>
#ifdef SC_DEBUG<br>
<br>
printf("ERROR: Listing SC readers!\n");<br>
<br>
#endif<br>
<br>
SCardReleaseContext( *hContext );<br>
<br>
}<br>
<br>
}<br>
<br>
if (SCARD_S_SUCCESS == rv)<br>
<br>
{<br>
<br>
<br>
<br>
#ifdef SC_DEBUG<br>
<br>
printf( "Listing SC readers...\n" );<br>
<br>
#endif<br>
<br>
mszReaders = calloc( dwReaders, sizeof(char) );<br>
<br>
rv = SCardListReaders( *hContext,<br>
<br>
NULL,<br>
<br>
*mszReaders,<br>
<br>
&dwReaders );<br>
<br>
if(SCARD_S_SUCCESS != rv)<br>
<br>
{<br>
<br>
#ifdef SC_DEBUG<br>
<br>
printf( "ERROR: Listing SC readers!\n" );<br>
<br>
#endif<br>
<br>
SCardFreeMemory( *hContext, *mszReaders );<br>
<br>
SCardReleaseContext( *hContext );<br>
<br>
}<br>
<br>
}<br>
<br>
#endif<br>
<br>
if (SCARD_S_SUCCESS == rv)<br>
<br>
{<br>
<br>
<br>
<br>
#ifdef SC_DEBUG<br>
<br>
printf( "Connecting to SC...\n" );<br>
<br>
#endif<br>
<br>
rv = SCardConnect( *hContext,<br>
<br>
*mszReaders,<br>
<br>
SCARD_SHARE_SHARED,<br>
<br>
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,<br>
<br>
hCard,<br>
<br>
&dwActiveProtocol);<br>
<br>
if (SCARD_S_SUCCESS != rv)<br>
<br>
{<br>
<br>
#ifdef SC_DEBUG<br>
<br>
printf("ERROR: Connecting to SC!\n");<br>
<br>
#endif<br>
<br>
}<br>
<br>
}<br>
<br>
SCardFreeMemory(*hContext, *mszReaders);<br>
<br>
SCardReleaseContext(*hContext)<wbr>;<br>
<br>
<br>
<br>
fflush(stdout);<br>
<br>
return rv;<br>
<br>
}<br>
<br>
<br>
<br>
void waitForSmartcardConnect()<br>
<br>
{<br>
<br>
SCARDCONTEXT hContext;<br>
<br>
SCARDHANDLE hCard;<br>
<br>
LPTSTR mszReaders;<br>
<br>
<br>
<br>
while(checkSmartcard(&<wbr>hContext, &hCard, &mszReaders) != 0)<br>
<br>
{<br>
<br>
sleep(1);<br>
<br>
}<br>
<br>
}<br>
<br>
<br>
<br>
void waitForSmartcardDisconnect()<br>
<br>
{<br>
<br>
SCARDCONTEXT hContext;<br>
<br>
SCARDHANDLE hCard;<br>
<br>
LPTSTR mszReaders;<br>
<br>
<br>
<br>
while(checkSmartcard(&<wbr>hContext, &hCard, &mszReaders) == 0)<br>
<br>
{<br>
<br>
sleep(1);<br>
<br>
}<br>
<br>
}<br>
<br>
______________________________<wbr>_________________<br>
Pcsclite-muscle mailing list<br>
<a href="mailto:Pcsclite-muscle@lists.alioth.debian.org">Pcsclite-muscle@lists.alioth.<wbr>debian.org</a><br>
<a href="http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle" rel="noreferrer" target="_blank">http://lists.alioth.debian.<wbr>org/cgi-bin/mailman/listinfo/<wbr>pcsclite-muscle</a><br>
</blockquote></div><br></div></div></div>