Hi.

What is the status of multithreaded access to pcsc-lite? Is it supposed to work?

SCardGetStatusChange(timeout=INFINITE) with latest pcsc-lite fails as it holds 
the mutex for ... infinite time :) The Windows test shows that a 
SCardGetStatusChange(timeout=0) is supposed to return even when a "infinitely" 
blocking call is going on.

I attach a simple test program written with python/pyscard and the output from 
Winows:

Context established!
PCSC Readers: ['OMNIKEY CardMan 1021 0']
----- Current reader and card states are: -------
OMNIKEY CardMan 1021 0 0x3B 0x6E 0x00 0xFF 0x45 0x73 0x74 0x45 0x49 0x44 0x20 
0x76 0x65 0x72 0x20 0x31 0x2E 0x30
        Card present in reader
        State changed
Launching a new thread
Sleeping a little ...
----- Please insert or remove a card ------------                               
        <--- don't really insert anything
Getting status without a timeout
Got statuses:                                                                   
                                <--- a non-blocking access in another thread 
returns right away.
OMNIKEY CardMan 1021 0 0x3B 0x6E 0x00 0xFF 0x45 0x73 0x74 0x45 0x49 0x44 0x20 
0x76 0x65 0x72 0x20 0x31 0x2E 0x30
        Card present in reader
        State changed
----- New reader and card states are: -----------
OMNIKEY CardMan 1021 0 
        Reader empty
        State changed
Released context.




This makes my re-written blocking C_WaitForSlotEvent() implementation in OpenSC 
unusable on non-windows platforms :(

I don't know enough about pcsc-lite internals to fix the problem.
#! /usr/bin/env python
"""
Sample for python PCSC wrapper module: Detect card insertion/removal

__author__ = "http://www.gemalto.com";

Copyright 2001-2009 gemalto
Author: Jean-Daniel Aussel, mailto:[email protected]

This file is part of pyscard.

pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
"""

from smartcard.scard import *
import smartcard.util
import time
from threading import Thread

srTreeATR = [0x3B, 0x77, 0x94, 0x00, 0x00, 0x82, 0x30, 0x00, 0x13, 0x6C, 0x9F, 0x22]
srTreeMask= [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]

def printstate(state):
    reader, eventstate, atr = state
    print reader + " " + smartcard.util.toHexString(atr, smartcard.util.HEX)
    if eventstate & SCARD_STATE_ATRMATCH:
        print '\tCard found'
    if eventstate & SCARD_STATE_UNAWARE:
        print '\tState unware'
    if eventstate & SCARD_STATE_IGNORE:
        print '\tIgnore reader'
    if eventstate & SCARD_STATE_UNAVAILABLE:
        print '\tReader unavailable'
    if eventstate & SCARD_STATE_EMPTY:
        print '\tReader empty'
    if eventstate & SCARD_STATE_PRESENT:
        print '\tCard present in reader'
    if eventstate & SCARD_STATE_EXCLUSIVE:
        print '\tCard allocated for exclusive use by another application'
    if eventstate & SCARD_STATE_INUSE:
        print '\tCard in used by another application but can be shared'
    if eventstate & SCARD_STATE_MUTE:
        print '\tCard is mute'
    if eventstate & SCARD_STATE_CHANGED:
        print '\tState changed'
    if eventstate & SCARD_STATE_UNKNOWN:
        print '\tState unknowned'


class OtherThread(Thread):
    def __init__(self, context, states, readers):
        Thread.__init__(self)
        self.context = context
        self.states = states
        self.readers = readers
    def run(self):
        print "Sleeping..."
        print time.sleep(2)
        print "StatusChange"
        readerstates = []
        for i in xrange(len(readers)):
            readerstates += [ (readers[i], SCARD_STATE_UNAWARE ) ]

        hresult, newstates = SCardGetStatusChange( hcontext, 0, readerstates )
        print 'States in current readers:'
        for i in newstates:
            printstate( i )
                    
                                            



try:
    hresult, hcontext = SCardEstablishContext( SCARD_SCOPE_USER )
    if hresult!=0:
        raise error, 'Failed to establish context: ' + SCardGetErrorMessage(hresult)
    print 'Context established!'

    try:
        hresult, readers = SCardListReaders( hcontext, [] )
        if hresult!=0:
            raise error, 'Failed to list readers: ' + SCardGetErrorMessage(hresult)
        print 'PCSC Readers:', readers

        readerstates = []
        for i in xrange(len(readers)):
            readerstates += [ (readers[i], SCARD_STATE_UNAWARE ) ]

        print '----- Current reader and card states are: -------'
        hresult, newstates = SCardGetStatusChange( hcontext, 0, readerstates )
        for i in newstates:
            printstate( i )
        newthread = OtherThread(hcontext, newstates, readers)
        newthread.start()

        print '----- Please insert or remove a card ------------'
        hresult, newstates = SCardGetStatusChange( hcontext, INFINITE, newstates )


        print '----- New reader and card states are: -----------'
        for i in newstates:
            printstate( i )


    finally:
        hresult = SCardReleaseContext( hcontext )
        if hresult!=0:
            raise error, 'Failed to release context: ' + SCardGetErrorMessage(hresult)
        print 'Released context.'

    import sys
    if 'win32'==sys.platform:
        print 'press Enter to continue'
        sys.stdin.read(1)

except error:
    import sys
    print sys.exc_info()[0], ':', sys.exc_info()[1]
-- 
Martin Paljak
http://martin.paljak.pri.ee
+372.515.6495




_______________________________________________
Muscle mailing list
[email protected]
http://lists.drizzle.com/mailman/listinfo/muscle

Reply via email to