pcsc-lite 1.6.5 (not yet released but the code is available in the
subversion repository or
here) contains a new feature that was described in the
TODO
file as:
power on the card only if an application requests a connection. See Alioth bug #301965. That could be implemented by polling the reader only if an application requests it.
How to power off a card
In previous versions of pcsc-lite, a card, when inserted, was always powered on. The only way to power off a card is to call
SCardDisconnect(SCARD_UNPOWER_CARD)
,
SCardEndTransaction(SCARD_UNPOWER_CARD)
or
SCardReconnect(SCARD_UNPOWER_CARD)
.
After the
SCardEndTransaction(SCARD_UNPOWER_CARD)
or
SCardReconnect(SCARD_UNPOWER_CARD)
calls the card is still used by the application. The power off action is just to force a cold reset to the card. So the card is powered on right after the power off.
Auto power off
After
SCardDisconnect()
the card is not used since the connection with the card is closed. It is the only case where the card may stay in the powered off.
dwDisposition
argument of
SCardDisconnect()
can be:
- SCARD_LEAVE_CARD - Do nothing.
- SCARD_RESET_CARD - Reset the card (warm reset).
- SCARD_UNPOWER_CARD - Unpower the card (cold reset).
- SCARD_EJECT_CARD - Eject the card.
SCARD_EJECT_CARD is not used. I do not know any smart card reader with mechanical features to eject a card.
If SCARD_UNPOWER_CARD is used the card is and will stay powered off
If SCARD_LEAVE_CARD or SCARD_RESET_CARD is used the card is still powered but is subject to a power off.
Auto power on
Once the card has been powered off it must be powered on again on the next use.
The only way to "use" a card is to call
SCardConnect()
. So when
SCardConnect()
is called and the card is not powered then the card is powered on first.
Smarter auto power off
The described scheme works great. One side effect is that the card may be powered off just before being used.
For example imagine the following scenario:
- you insert a card in the reader
- the card is powered on to get its ATR
- the card is not used by any application so the card is powered off
- an application was waiting in
SCardGetStatusChange()
and is now notified that a card is present
- the application call
SCardConnect()
to use the card
- the card is powered on again
To avoid the double power on action a delay is used before powering off the card in step 3. The card is powered off only if the card is not used during 5 seconds.
For the same reason the card is not powered off just at
SCardDisconnect()
but after being unused during 5 seconds.
Compilation options
The compilation options are in the file
src/pcscd.h.in
.
/** time to wait before powering down an unused card */
#define PCSCLITE_POWER_OFF_GRACE_PERIOD 5*1000 /* 5 second */
/* Uncomment the next line if you do NOT want to use auto power off */
/* #define DISABLE_ON_DEMAND_POWER_ON */
/* Uncomment the next line if you do not want the card to be powered on when inserted */
/* #define DISABLE_AUTO_POWER_ON */
You can change the 5 seconds delay before the automatic power off:
PCSCLITE_POWER_OFF_GRACE_PERIOD
. It looks like on Windows the delay is 15 seconds.
If you do not like the new feature then define
DISABLE_ON_DEMAND_POWER_ON
and you will continue to have the previous behavior.
If you do not want the card to be powered on on insertion then define
DISABLE_AUTO_POWER_ON
. With this option the card will be powered on
only when
SCardConnect()
is called, not when the card is inserted in the reader. This has side effects and is not an innocent choice.
SCardGetStatusChange()
will report a card is present but will not report the card ATR. To get the card ATR you have to use
SCardStatus()
or call
SCardGetStatusChange()
once again after the card has been powered off using
SCardConnect()
.
Impacts on the reader drivers
In order to respect the 5 seconds of delay I had to replace
TAG_IFD_POLLING_THREAD
by
TAG_IFD_POLLING_THREAD_WITH_TIMEOUT
and add a timeout parameter.
I modified my
CCID driver to use the new function. I do not know any other driver supporting
TAG_IFD_POLLING_THREAD
and needing an upgrade.
If your reader driver does not support
TAG_IFD_POLLING_THREAD
the delay before powering off the card will be 400 milliseconds (
PCSCLITE_STATUS_POLL_RATE
) instead of 5 seconds.
Conclusion
The power consumption of the smart card reader should be reduced a bit when the card is not powered on.
Some readers have a LED to indicate the state of the reader. For example the
Gemalto GemPC Twin reader has a blinking LED when the reader is connected and a still LED when the card is powered on. I generally use the LED to know if the CCID driver and pcsc-lite are working correctly. A still LED indicates the PC/SC layer is working correctly. With the new mechanism the LED is useful only during 5 seconds after inserting the card. A blinking instead of still LED does not, always, indicates a broken PC/SC layer any more.
Powering off the card is also a new step on the road to suspending the reader at the USB level, and further reduce the power consumption.