pcsc-lite: (much) faster SCardDisconnect()
Since pcsc-lite 1.8.18 the function SCardDisconnect() has a new behaviour.
Some history
Always on
At the beginning of pcsc-lite (circa 1999) the card was always powered on when inserted in a smart card reader. The code was simple: when a card is inserted in a reader then power on the card. This worked great.At that time the USB 1.1 was quite new and most smart card readers were using a serial port and an external power supply.
Auto power off
In 2010 most of the smart card readers were connected using USB and used the USB cable to get the power. So it was a good idea to power off a smart card that is not used to reduce the power consumed in particular when you use a laptop computer.So I implemented a mechanism to automatically power off an unused card. The card is powered off if it is not used 5 seconds after the power on. See "Card auto power on and off" for more details.
SCardDisconnect(..., SCARD_UNPOWER_CARD)
would power off the card, power it on again and 5 seconds later, if not used, power off the card.Remove extra power on
SCardDisconnect(..., SCARD_UNPOWER_CARD)
would not return before the power on succeeds. This operation takes time because the reader has to get the ATR from the card. The application specifically used SCARD_UNPOWER_CARD
so we can expect the card will not be used after that.Since the card auto power on and off mechanism was already implemented in 2010 the card was already automatically powered on when needed. It was simple to modify the pcsc-lite code and remove the useless power on.
Benefit
The benefit is simple:SCardDisconnect(..., SCARD_UNPOWER_CARD)
is now much faster. I included some numbers in the patch commit message.Before the change:
SCardDisconnect(SCARD_UNPOWER_CARD)
in 61 msAfter the change:
SCardDisconnect(SCARD_UNPOWER_CARD)
in 1.4 msSpeedup (for the card used) = 61/1.4 = x44
If you use a card that is slower to power up then the gain is even higher.
I think a speedup of x10 or x100 on a PC/SC function deserve a blog article, even if
SCardDisconnect(..., SCARD_UNPOWER_CARD)
is not always on the performance critical path of an application.