Important!

Blog moved to https://blog.apdu.fr/

I moved my blog from https://ludovicrousseau.blogspot.com/ to https://blog.apdu.fr/ . Why? I wanted to move away from Blogger (owne...

Sunday, October 24, 2010

Card auto power on and off

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:
  1. you insert a card in the reader
  2. the card is powered on to get its ATR
  3. the card is not used by any application so the card is powered off
  4. an application was waiting in SCardGetStatusChange() and is now notified that a card is present
  5. the application call SCardConnect() to use the card
  6. 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.


Flattr this