#include "reader.h"
Reader::Reader(TokenCache &tc, const PCSC::ReaderState &state)
: cache(tc), mType(pcsc), mToken(NULL)
{
mName = state.name(); mPrintName = mName; secdebug("reader", "%p (%s) new PCSC reader", this, name().c_str());
}
Reader::Reader(TokenCache &tc, const string &identifier)
: cache(tc), mType(software), mToken(NULL)
{
mName = identifier;
mPrintName = mName;
secdebug("reader", "%p (%s) new software reader", this, name().c_str());
}
Reader::~Reader()
{
secdebug("reader", "%p (%s) destroyed", this, name().c_str());
}
bool Reader::isType(Type reqType) const
{
return reqType == this->type();
}
void Reader::kill()
{
if (mToken)
removeToken();
NodeCore::kill();
}
void Reader::update(const PCSC::ReaderState &state)
{
unsigned long oldState = mState.state();
mState = state;
mState.name(mName.c_str());
try {
if (state.state(SCARD_STATE_UNAVAILABLE)) {
secdebug("reader", "%p (%s) unavailable (0x%lx)",
this, name().c_str(), state.state());
if (mToken)
removeToken();
} else if (state.state(SCARD_STATE_EMPTY)) {
secdebug("reader", "%p (%s) empty (0x%lx)",
this, name().c_str(), state.state());
if (mToken)
removeToken();
} else if (state.state(SCARD_STATE_PRESENT)) {
secdebug("reader", "%p (%s) card present (0x%lx)",
this, name().c_str(), state.state());
if (mToken && CssmData(state) != CssmData(pcscState()))
removeToken(); if (!mToken)
insertToken(NULL);
} else {
secdebug("reader", "%p (%s) unexpected state change (0x%lx to 0x%lx)",
this, name().c_str(), oldState, state.state());
}
} catch (...) {
secdebug("reader", "state update exception (ignored)");
}
}
void Reader::insertToken(TokenDaemon *tokend)
{
RefPointer<Token> token = new Token();
token->insert(*this, tokend);
mToken = token;
addReference(*token);
secdebug("reader", "%p (%s) inserted token %p",
this, name().c_str(), mToken);
}
void Reader::removeToken()
{
secdebug("reader", "%p (%s) removing token %p",
this, name().c_str(), mToken);
assert(mToken);
mToken->remove();
removeReference(*mToken);
mToken = NULL;
}
#if defined(DEBUGDUMP)
void Reader::dumpNode()
{
PerGlobal::dumpNode();
Debug::dump(" [%s] state=0x%lx", name().c_str(), mState.state());
}
#endif //DEBUGDUMP