<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>