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