Logo Search packages:      
Sourcecode: coreutils version File versions  Download package

pcsc++.h

/*
 * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
 * 
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */


//
// pcsc++ - PCSC client interface layer in C++
//
// NOTE: TO BE MOVED TO security_utilities LAYER.
//
#ifndef _H_PCSC_PP
#define _H_PCSC_PP

#include <security_utilities/utilities.h>
#include <security_utilities/errors.h>
#include <security_utilities/transactions.h>
#include <security_utilities/debugging.h>
#include <PCSC/winscard.h>
#include <vector>
#include <string>

#include <cstdio>


namespace Security {
namespace PCSC {


//
// PCSC-domain error exceptions
//
class Error : public CommonError {
public:
      Error(unsigned long err);

    const unsigned long error;
      OSStatus osStatus() const;
      int unixError() const;
      const char *what () const throw ();
      
      static void check(unsigned long err) { if (err != SCARD_S_SUCCESS) throwMe(err); }
      static void throwMe(unsigned long err);

private:
      IFDEBUG(void debugDiagnose(const void *id) const);
};


//
// A PODWrapper for the PCSC READERSTATE structure
//
class ReaderState : public PodWrapper<ReaderState, SCARD_READERSTATE> {
public:
      void set(const char *name, unsigned long known = SCARD_STATE_UNAWARE);
      
      const char *name() const      { return szReader; }
      void name(const char *s)      { szReader = s; }

      unsigned long lastKnown() const { return dwCurrentState; }
      void lastKnown(unsigned long s);

      unsigned long state() const { return dwEventState; }
      bool state(unsigned long it) const { return state() & it; }
      bool changed() const          { return state(SCARD_STATE_CHANGED); }
      
      template <class T>
      T * &userData() { return reinterpret_cast<T * &>(pvUserData); }
      
      // DataOid access to the ATR data
      const void *data() const { return rgbAtr; }
      size_t length() const { return cbAtr; }
      void setATR(const void *atr, size_t size);
      
      IFDUMP(void dump());
};


//
// A Session represents the entire process state for the PCSC protocol
//
class Session {
      friend class Card;
public:
      Session();
      virtual ~Session();

      void open();
      bool isOpen() const { return mIsOpen; }
      
      void listReaders(vector<string> &readers, const char *groups = NULL);
      
      void statusChange(ReaderState *readers, unsigned int nReaders, long timeout = 0);
      void statusChange(ReaderState &reader, long timeout = 0)
      { return statusChange(&reader, 1, timeout); }
      void statusChange(vector<ReaderState> &readers, long timeout = 0)
      { return statusChange(&readers[0], readers.size(), timeout); }
      

private:
      bool check(long rc);
      
private:
      bool mIsOpen;
      SCARDCONTEXT mContext;
      std::vector<char> mReaderBuffer;
};


//
// A Card represents a PCSC-managed card slot
//
class Card {
public:
      static const unsigned long defaultProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
      
      Card();
      virtual ~Card();

      void connect(Session &session, const char *reader,
            unsigned long share = SCARD_SHARE_SHARED,
            unsigned long protocols = defaultProtocols);
      void reconnect(unsigned long share = SCARD_SHARE_SHARED,
            unsigned long protocols = defaultProtocols,
            unsigned long initialization = SCARD_LEAVE_CARD);
      void disconnect(unsigned long disposition = SCARD_LEAVE_CARD);
      virtual void didDisconnect();
      virtual void didEnd();

      void checkReset(unsigned int rv);
      bool isConnected() const { return mConnectedState == kConnected; }
      bool isInTransaction() const { return mTransactionNestLevel > 0; }

      void transmit(const unsigned char *pbSendBuffer, size_t cbSendLength,
            unsigned char *pbRecvBuffer, size_t &pcbRecvLength);

      // primitive transaction interface
      void begin();
      void end(unsigned long disposition = SCARD_LEAVE_CARD);
      void cancel();

protected:
      void setIOType(unsigned long activeProtocol);

      IFDUMP(void dump(const char *direction, const unsigned char *buffer, size_t length);)
      
private:
      enum
      {
            kInitial,
            kConnected,
            kDisconnected
      } mConnectedState;
            
      int32_t mHandle;
      int mTransactionNestLevel;
      SCARD_IO_REQUEST *mIOType;
};


//
// A PCSC-layer transaction (exclusive sequence of calls)
//
class Transaction : public ManagedTransaction<Card> {
public:
      Transaction(Card &card, Outcome outcome = conditional)
            : ManagedTransaction<Card>(card, outcome), mDisposition(SCARD_LEAVE_CARD) { }
      
      void disposition(unsigned long disp);     // change disposition on successful outcome

protected:
      void commitAction();

private:
      unsigned long mDisposition;                     // disposition on success
};


}   // namespce PCSC
}   // namespace Security


#endif //_H_PCSC_PP

Generated by  Doxygen 1.6.0   Back to index