[Pcsclite-cvs-commit] r5328 - in /trunk/PCSC: TODO src/PCSC/ifdhandler.h src/eventhandler.c src/eventhandler.h src/pcscd.h.in src/readerfactory.c src/readerfactory.h src/winscard.c
rousseau at users.alioth.debian.org
rousseau at users.alioth.debian.org
Thu Oct 21 18:50:34 UTC 2010
Author: rousseau
Date: Thu Oct 21 18:50:24 2010
New Revision: 5328
URL: http://svn.debian.org/wsvn/pcsclite/?sc=1&rev=5328
Log:
Power on the card _only_ if an application requests a connection
see Alioth bug #301965
You can disable the feature using DISABLE_ON_DEMAND_POWER_ON in
src/eventhandler.c
Modified:
trunk/PCSC/TODO
trunk/PCSC/src/PCSC/ifdhandler.h
trunk/PCSC/src/eventhandler.c
trunk/PCSC/src/eventhandler.h
trunk/PCSC/src/pcscd.h.in
trunk/PCSC/src/readerfactory.c
trunk/PCSC/src/readerfactory.h
trunk/PCSC/src/winscard.c
Modified: trunk/PCSC/TODO
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/TODO?rev=5328&op=diff
==============================================================================
--- trunk/PCSC/TODO (original)
+++ trunk/PCSC/TODO Thu Oct 21 18:50:24 2010
@@ -1,9 +1,4 @@
- include Apple patches and improvements (if possible/needed)
-
-- 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.
- allow to have pcscd and libpcsclite on two different machines.
That would be needed to support remote PAM login.
@@ -30,4 +25,4 @@
- use static driver instead of reader polling and dynamic driver loading
-March 2010
+October 2010
Modified: trunk/PCSC/src/PCSC/ifdhandler.h
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/PCSC/ifdhandler.h?rev=5328&op=diff
==============================================================================
--- trunk/PCSC/src/PCSC/ifdhandler.h (original)
+++ trunk/PCSC/src/PCSC/ifdhandler.h Thu Oct 21 18:50:24 2010
@@ -307,9 +307,10 @@
#define TAG_IFD_THREAD_SAFE 0x0FAD /**< driver is thread safe */
#define TAG_IFD_SLOTS_NUMBER 0x0FAE /**< number of slots of the reader */
#define TAG_IFD_SIMULTANEOUS_ACCESS 0x0FAF /**< number of reader the driver can manage */
-#define TAG_IFD_POLLING_THREAD 0x0FB0 /**< driver uses a polling thread */
+#define TAG_IFD_POLLING_THREAD 0x0FB0 /**< not used. See TAG_IFD_POLLING_THREAD_WITH_TIMEOUT */
#define TAG_IFD_POLLING_THREAD_KILLABLE 0x0FB1 /**< the polling thread can be killed */
#define TAG_IFD_STOP_POLLING_THREAD 0x0FB2 /**< method used to stop the polling thread (instead of just pthread_kill()) */
+#define TAG_IFD_POLLING_THREAD_WITH_TIMEOUT 0x0FB3 /**< driver uses a polling thread with a timeout parameter */
/*
* IFD Handler version number enummerations
Modified: trunk/PCSC/src/eventhandler.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/eventhandler.c?rev=5328&op=diff
==============================================================================
--- trunk/PCSC/src/eventhandler.c (original)
+++ trunk/PCSC/src/eventhandler.c Thu Oct 21 18:50:24 2010
@@ -39,6 +39,9 @@
#include "winscard_svc.h"
#include "simclist.h"
+/* Uncomment the next line if you do NOT want to use auto power off */
+/* #define DISABLE_ON_DEMAND_POWER_ON */
+
static list_t ClientsWaitingForEvent; /**< list of client file descriptors */
pthread_mutex_t ClientsWaitingForEvent_lock; /**< lock for the above list */
@@ -204,8 +207,7 @@
return SCARD_S_SUCCESS;
}
-LONG EHSpawnEventHandler(READER_CONTEXT * rContext,
- RESPONSECODE (*card_event)(DWORD))
+LONG EHSpawnEventHandler(READER_CONTEXT * rContext)
{
LONG rv;
DWORD dwStatus = 0;
@@ -218,7 +220,6 @@
return SCARD_F_UNKNOWN_ERROR;
}
- rContext->pthCardEvent = card_event;
rv = ThreadCreate(&rContext->pthThread, 0,
(PCSCLITE_THREAD_FUNCTION( ))EHStatusHandlerThread, (LPVOID) rContext);
if (rv)
@@ -264,6 +265,7 @@
if (rv == IFD_SUCCESS)
{
readerState = SCARD_PRESENT | SCARD_POWERED | SCARD_NEGOTIABLE;
+ rContext->powerState = POWER_STATE_POWERED;
if (rContext->readerState->cardAtrLength > 0)
{
@@ -277,6 +279,7 @@
else
{
readerState = SCARD_PRESENT | SCARD_SWALLOWED;
+ rContext->powerState = POWER_STATE_UNPOWERED;
Log3(PCSC_LOG_ERROR, "Error powering up card: %d 0x%04X", rv, rv);
}
@@ -365,10 +368,12 @@
if (rv == IFD_SUCCESS)
{
rContext->readerState->readerState = SCARD_PRESENT | SCARD_POWERED | SCARD_NEGOTIABLE;
+ rContext->powerState = POWER_STATE_POWERED;
}
else
{
rContext->readerState->readerState = SCARD_PRESENT | SCARD_SWALLOWED;
+ rContext->powerState = POWER_STATE_UNPOWERED;
rContext->readerState->cardAtrLength = 0;
}
@@ -409,13 +414,42 @@
if (rContext->pthCardEvent)
{
int ret;
-
- ret = rContext->pthCardEvent(rContext->slot);
+ int timeout;
+
+#ifndef DISABLE_ON_DEMAND_POWER_ON
+ if (POWER_STATE_POWERED == rContext->powerState)
+ /* The card is powered but not yet used */
+ timeout = PCSCLITE_POWER_OFF_GRACE_PERIOD;
+ else
+ /* The card is already in use or not used at all */
+#endif
+ timeout = PCSCLITE_STATUS_EVENT_TIMEOUT;
+
+ ret = rContext->pthCardEvent(rContext->slot, timeout);
if (IFD_NO_SUCH_DEVICE == ret)
(void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE);
}
else
(void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE);
+
+#ifndef DISABLE_ON_DEMAND_POWER_ON
+ /* the card is powered but not used */
+ if (POWER_STATE_POWERED == rContext->powerState)
+ {
+ /* power down */
+ IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
+ rContext->powerState = POWER_STATE_UNPOWERED;
+
+ /* the protocol is unset after a power down */
+ rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
+ }
+
+ /* the card was in use */
+ if (POWER_STATE_GRACE_PERIOD == rContext->powerState)
+ /* the next state should be UNPOWERED unless the
+ * card is used again */
+ rContext->powerState = POWER_STATE_POWERED;
+#endif
if (rContext->hLockId == 0xFFFF)
{
Modified: trunk/PCSC/src/eventhandler.h
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/eventhandler.h?rev=5328&op=diff
==============================================================================
--- trunk/PCSC/src/eventhandler.h (original)
+++ trunk/PCSC/src/eventhandler.h Thu Oct 21 18:50:24 2010
@@ -47,8 +47,7 @@
LONG EHUnregisterClientForEvent(int32_t filedes);
LONG EHSignalEventToClients(void);
LONG EHInitializeEventStructures(void);
- LONG EHSpawnEventHandler(READER_CONTEXT *,
- /*@null@*/ RESPONSECODE (*)(DWORD));
+ LONG EHSpawnEventHandler(READER_CONTEXT *);
LONG EHDestroyEventHandler(READER_CONTEXT *);
/** One application is using the reader */
Modified: trunk/PCSC/src/pcscd.h.in
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/pcscd.h.in?rev=5328&op=diff
==============================================================================
--- trunk/PCSC/src/pcscd.h.in (original)
+++ trunk/PCSC/src/pcscd.h.in Thu Oct 21 18:50:24 2010
@@ -46,4 +46,20 @@
#define MAX_BUFFER_SIZE 264 /**< Maximum Tx/Rx Buffer for get/set attributes */
#define MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1<<16) + 3) /**< max APDU (64K + APDU + Lc + Le) Tx/Rx Buffer */
+/** Different values for struct ReaderContext powerState field */
+enum
+{
+ POWER_STATE_UNPOWERED, /**< auto power off */
+ POWER_STATE_POWERED, /**< powered */
+ POWER_STATE_GRACE_PERIOD, /**< card was in use */
+ POWER_STATE_INUSE /**< card is used */
+};
+
+/** time to wait before powering down an unused card */
+#define PCSCLITE_POWER_OFF_GRACE_PERIOD 5*1000 /* 5 second */
+
+/** normal timeout for pthCardEvent driver function when
+ * no card or card in use */
+#define PCSCLITE_STATUS_EVENT_TIMEOUT 10*60*1000 /* 10 minutes */
+
#endif
Modified: trunk/PCSC/src/readerfactory.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/readerfactory.c?rev=5328&op=diff
==============================================================================
--- trunk/PCSC/src/readerfactory.c (original)
+++ trunk/PCSC/src/readerfactory.c Thu Oct 21 18:50:24 2010
@@ -185,6 +185,7 @@
(sReadersContexts[dwContext])->vHandle = NULL;
(sReadersContexts[dwContext])->pFeeds = NULL;
(sReadersContexts[dwContext])->pMutex = NULL;
+ sReadersContexts[dwContext]->pthCardEvent = NULL;
(sReadersContexts[dwContext])->dwIdentity =
(dwContext + 1) << IDENTITY_SHIFT;
@@ -272,21 +273,23 @@
/* asynchronous card movement? */
{
- RESPONSECODE (*fct)(DWORD) = NULL;
+ RESPONSECODE (*fct)(DWORD, int) = NULL;
dwGetSize = sizeof(fct);
rv = IFDGetCapabilities((sReadersContexts[dwContext]),
- TAG_IFD_POLLING_THREAD, &dwGetSize, (PUCHAR)&fct);
+ TAG_IFD_POLLING_THREAD_WITH_TIMEOUT, &dwGetSize, (PUCHAR)&fct);
if ((rv != SCARD_S_SUCCESS) || (dwGetSize != sizeof(fct)))
{
- fct = NULL;
Log1(PCSC_LOG_INFO, "Using the pcscd polling thread");
}
else
+ {
+ sReadersContexts[dwContext]->pthCardEvent = fct;
Log1(PCSC_LOG_INFO, "Using the reader polling thread");
-
- rv = EHSpawnEventHandler(sReadersContexts[dwContext], fct);
+ }
+
+ rv = EHSpawnEventHandler(sReadersContexts[dwContext]);
if (rv != SCARD_S_SUCCESS)
{
Log2(PCSC_LOG_ERROR, "%s init failed.", readerName);
@@ -319,7 +322,7 @@
{
char *tmpReader = NULL;
DWORD dwContextB = 0;
- RESPONSECODE (*fct)(DWORD) = NULL;
+ RESPONSECODE (*fct)(DWORD, int) = NULL;
/* We must find an empty spot to put the reader structure */
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
@@ -428,16 +431,18 @@
dwGetSize = sizeof(fct);
rv = IFDGetCapabilities((sReadersContexts[dwContextB]),
- TAG_IFD_POLLING_THREAD, &dwGetSize, (PUCHAR)&fct);
+ TAG_IFD_POLLING_THREAD_WITH_TIMEOUT, &dwGetSize, (PUCHAR)&fct);
if ((rv != SCARD_S_SUCCESS) || (dwGetSize != sizeof(fct)))
{
- fct = NULL;
Log1(PCSC_LOG_INFO, "Using the pcscd polling thread");
}
else
+ {
+ sReadersContexts[dwContextB]->pthCardEvent = fct;
Log1(PCSC_LOG_INFO, "Using the reader polling thread");
-
- rv = EHSpawnEventHandler(sReadersContexts[dwContextB], fct);
+ }
+
+ rv = EHSpawnEventHandler(sReadersContexts[dwContextB]);
if (rv != SCARD_S_SUCCESS)
{
Log2(PCSC_LOG_ERROR, "%s init failed.", readerName);
Modified: trunk/PCSC/src/readerfactory.h
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/readerfactory.h?rev=5328&op=diff
==============================================================================
--- trunk/PCSC/src/readerfactory.h (original)
+++ trunk/PCSC/src/readerfactory.h Thu Oct 21 18:50:24 2010
@@ -108,7 +108,7 @@
char *library; /**< Library Path */
char *device; /**< Device Name */
pthread_t pthThread; /**< Event polling thread */
- RESPONSECODE (*pthCardEvent)(DWORD); /**< Card Event sync */
+ RESPONSECODE (*pthCardEvent)(DWORD, int); /**< Card Event sync */
pthread_mutex_t *mMutex; /**< Mutex for this connection */
list_t handlesList;
pthread_mutex_t handlesList_lock; /**< lock for the above list */
@@ -129,6 +129,7 @@
int32_t contexts; /**< Number of open contexts */
int * pFeeds; /**< Number of shared client to lib */
int * pMutex; /**< Number of client to mutex */
+ int powerState; /**< auto power off state */
struct pubReaderStatesList *readerState; /**< link to the reader state */
/* we can't use READER_CONTEXT * here since eventhandler.h can't be
Modified: trunk/PCSC/src/winscard.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard.c?rev=5328&op=diff
==============================================================================
--- trunk/PCSC/src/winscard.c (original)
+++ trunk/PCSC/src/winscard.c Thu Oct 21 18:50:24 2010
@@ -342,6 +342,20 @@
}
}
+ /* Power on (again) the card if needed */
+ if (POWER_STATE_UNPOWERED == rContext->powerState)
+ {
+ DWORD dwAtrLen;
+
+ dwAtrLen = sizeof(rContext->readerState->cardAtr);
+ Log0(PCSC_LOG_CRITICAL);
+ rv = IFDPowerICC(rContext, IFD_POWER_UP,
+ rContext->readerState->cardAtr, &dwAtrLen);
+ rContext->readerState->cardAtrLength = dwAtrLen;
+ }
+
+ /* the card is now in use */
+ rContext->powerState = POWER_STATE_INUSE;
/*******************************************
*
@@ -943,6 +957,26 @@
rContext->contexts = 0;
}
+ if (PCSCLITE_SHARING_NO_CONTEXT == rContext->contexts)
+ {
+ RESPONSECODE (*fct)(DWORD) = NULL;
+ DWORD dwGetSize;
+
+ rContext->powerState = POWER_STATE_GRACE_PERIOD;
+
+ /* ask to stop the "polling" thread so it can be restarted using
+ * the correct timeout */
+ dwGetSize = sizeof(fct);
+ rv = IFDGetCapabilities(rContext, TAG_IFD_STOP_POLLING_THREAD,
+ &dwGetSize, (PUCHAR)&fct);
+
+ if ((IFD_SUCCESS == rv) && (dwGetSize == sizeof(fct)))
+ {
+ Log1(PCSC_LOG_INFO, "Stoping polling thread");
+ fct(rContext->slot);
+ }
+ }
+
/*
* Propagate new state to reader state
*/
More information about the Pcsclite-cvs-commit
mailing list