/***************************************************************************
  $RCSfile: ctcard.h,v $
                             -------------------
    cvs         : $Id: ctcard.h,v 1.18 2003/06/16 20:31:03 aquamaniac Exp $
    begin       : Tue Aug 28 2001
    copyright   : (C) 2001 by Martin Preuss
    email       : martin@libchipcard.de


 ***************************************************************************
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
 *   MA  02111-1307  USA                                                   *
 *                                                                         *
 ***************************************************************************/

/**
 * @file ctcard.h
 * @short Contains the definition of CTCard.
 */

/**
 * @mainpage Libchipcard Documentation Main Page
 *
 * @section quickstart Quickstart
 * The main class you'll have to deal with is @ref CTCard and its derived
 * classes. So if you want immediately start coding please go to the
 * documentation of @ref CTCard.<br>
 * If you are more interested in the new Card File System then
 * @ref CTCardFS is your friend.
 *
 * @section whatis What Is Libchipcard ?
 * %Libchipcard is a library for easy access to smart cards. It is written
 * in C++ and should therefore work on most Unix-like platforms, and it also
 * works under WIN32.
 *
 * @section whatneed What Does Libchipcard Need ?
 * It needs
 * <ul>
 *  <li>
 *   card reader terminal supported by your operating system
 *  </li>
 *  <li>
 *   a driver for that reader (called CTAPI). The homepage of
 *   <a href="http://www.libchipcard.de">libchipcard</a> provides a list of
 *   links to drivers for some readers.
 *  </li>
 *  <li>
 *   OpenSSL: This is needed for encryption of data on a smart card using
 *   the @ref CTCardFS and for encryption of traffic between client and
 *   server.
 *  </li>
 * </ul>
 *
 * @section whatrec What Is Recommended ?
 * %Libchipcard works best when the following packages are provided:
 * <ul>
 *  <li>
 *   QT/KDE: %Libchipcard provides some KDE-tools. You will need KDE and QT
 *   in order to use them. KDE/QT 2 and 3 are supported.
 *  </li>
 * </ul>
 *
 * @section authors Authors
 * Martin Preu&szlig; &lt;
 * <a href="mailto:martin@libchipcard.de">martin@libchipcard.de</a>
 * &gt;
 *
 */

/**
 * @defgroup c_api C API
 *
 * This group contains the functions of the C core API of LibChipCard. This
 * is internally used by the @ref CTCard and derived classes.
 */

/**
 * @defgroup cards Card Classes
 *
 * This group contains card classes
 */

/**
 * @defgroup gcards General Card Classes
 * @ingroup cards
 *
 * This group contains general card classes (for memory cards and processor
 * cards)
 */

/**
 * @defgroup scards Special Card Classes
 *
 * This group contains classes which deal with special cards (like HBCI
 * cards and others)
 */

/**
 * @defgroup misc This and That
 *
 * This group contains several classes which do not belong to any other
 * group.
 */

/**
 * @defgroup status Status and error classes
 *
 * Contains classes that flag errors or give a kind of status.
 */


/**
 * @defgroup cardfs Card File System
 *
 * This group contains the classes of the LibChipcard Card File System.
 */

/**
 * @defgroup corecardfs Core of the Card File System
 * @ingroup cardfs
 *
 * This group contains classes of the core of the Card File System.
 */

/**
 * @defgroup llcardfs Low Level Card File System
 * @ingroup cardfs
 * This group contains quite low level classes for direct access to the
 * Card File System
 */

/**
 * @defgroup hlcardfs Higher Level Card File System
 * @ingroup cardfs
 *
 * This group contains higher level classes of the Card File System.
 * The main class here is @ref CTCardFS.
 */


/**
 * @defgroup netrpc Networking and RPC
 *
 * Classes which deal with network operations or perform remote procedure
 * calls.
 */


#ifndef CTCARD_H
#define CTCARD_H

class CTCard;


#include <string>
#include <list>

#include <chipcard/libchipcard.h>
#include <chipcard/cterror.h>
#include <chipcard/ctpointer.h>
#include <chipcard/ctcommand.h>
#include <chipcard/ctreadercontext.h>
#include <chipcard/ctreadertrader.h>
#include <chipcard/ctcardbase.h>


/**
 * This is just to let you mount/unmount a card, request its status
 * etc. It is very general. Special things are done in the classes
 * which inherit this one (like @ref CTMemoryCard and @ref CTProcessorCard.
 * This class (and its children) is the C++ interface to libchipcard.
 * When there is interaction with the card reader/card necessary then this
 * class will automatically create all other objects/structs whatsoever on
 * the fly. These things are all hidden from you, so you only have to
 * concentrate on this class here.
 * @ingroup gcards
 * @short This class describes a chipcard.
 * @author Martin Preuss<martin@libchipcard.de>
 */
class CHIPCARD_API CTCard: public CTCardBase {
  friend class CTCardTrader;
private:
  unsigned int _memsize;
  unsigned int _timeout;

  string _cardTypes;

  string _cmdSelectFile;
  string _cmdSelectFileId;
  string _cmdReadBinary;
  string _cmdUpdateBinary;

  int _calculateMemorySize(const string &atr);

  CTError _locateCommandReader(const string &command,
			       const string &reader,
			       string &result);
  CTError _locateCommand(const string &command,
			 string &result);

private:
  CTCard(const CTReaderContext &rc);

protected:
  virtual CallBackResult callback(bool first);

public:
  /** @name Constructors/Destructor
   *
   */
  //@{

  /**
   * This constructor is mainly used by derived classes to transform
   * a basic CTCard object to a more special one. This allows opening a
   * card as a CTCard object and then create e.g. a CTMemoryCard from
   * this one. The source card will be immediately closed. The only thing
   * you should do with it is to delete it. You should NOT use it any
   * longer !!
   * @param c reference to the CTCard object to be transformed
   * @author Martin Preuss<martin@libchipcard.de>
   */
  CTCard(const CTCard &c);

  virtual ~CTCard();
  //@}

  /** @name Opening and closing operations
   *
   * Methods to connect and disconnect the card. Most other methods
   * only work if the card is open.
   */
  //@{
  /**
   * Opens the card for usage.
   * This way the card is powered on.
   * This method does some basic checks and retrieves basic information
   * about the card (whether it is a memory card or a processor card,
   * the size of the memory etc).
   * When this method successfully returns the card may be used.
   * @author Martin Preuss<martin@libchipcard.de>
   * @return CTError object that holds the result (call isOk() to see if
   * there was an error)
   */
  virtual CTError openCard();

  /**
   * Call this if you have finished working with the card. After this
   * method is called you may safely remove the card from the reader.
   * @author Martin Preuss<martin@libchipcard.de>
   * @return CTError object that holds the result (call isOk() to see if
   * there was an error)
   */
  virtual CTError closeCard(bool force=false);

  /**
   * When this method is called normally the card is already opened by
   * means of @ref openCard(). However, it is likely that openCard() has
   * been called assuming this card is only a CTCard() object, nothing
   * special. You may then call THIS method here on all known card classes
   * to check for the type of this card.
   * This method must assume that any file on the card is already selected,
   * so it is in most cases a good idea to select the MF as the first action
   * of this method.
   * If the executing class finds that the card inserted is not of a type
   * it can handle then it MUST return an error.
   */
  virtual CTError reopenCard();
  //@}

  /** @name Informational methods
   *
   * These methods tell you about the type and the status of the card.
   */
  //@{
  /**
   * This method returns a short name of the class which handles this card.
   * A HBCI card for example returns "HBCICard". So you can use this method
   * to check for the type of the card.
   */
  virtual string cardType();

  /**
   * This method returns a comma separated list of all card types this card
   * inherits including the type of this card, e.g. a HBCI card would
   * return "CTProcessorCard, HBCICard". If you overload this method in your
   * own class (you SHOULD) you simply have to call this method of the
   * class it directly inherits. That class will then do the same, so that
   * there is a list upon return.
   */
  virtual string cardTypes();

  /**
   * Returns true if the card is a processor card.
   * This is only valid if the card is open.
   * @author Martin Preuss<martin@libchipcard.de>
   */
  bool isProcessorCard() const ;

  /**
   * Returns the size of the memory on the card. Mostly used with
   * memory cards, while processor cards sometimes return 0 (like the
   * hbci card does). Please note that some cards seem to be lieing about
   * their size !
   * This is only valid if the card is open.
   * @author Martin Preuss<martin@libchipcard.de>
   * @return size of memory in bytes
   */
  unsigned int memorySize() const { return _memsize;};

  //@}


  /** @name Commands
   *
   * These methods allow you to send a command to the card. Of course the
   * card needs to be already open.
   */
  //@{
  CTError makeAPDU(const string &command,
		   string &cmdCache,
		   string &apdu,
		   const string &param1,
		   const string &param2,
		   const string &param3,
		   const string &param4,
		   const string &param5);

  /**
   * Sends a command to the card reader terminal and retrieves its answer.
   * When this method returns the members lr, sw1,
   * sw2 and data are changed to reflect the answer.
   * This method is used by EVERY other command method
   * (like @ref selectFile(), @ref readBinary() etc).
   * @author Martin Preuss<martin@libchipcard.de>
   * @param cmd reference to the CTCommand struct
   * @return @ref CTError object that holds the result (call isOk() to see if
   * there was an error)
   */
  CTError execCommand(CTCommand &cmd);

  /**
   * This method sends a command using the config file driven command engine.
   * You specify the name of the command (like "read_binary" and the
   * parameters to it (for "read_binary" this would be the offset and size of
   * the data to read).
   * @return reuslt of the operation (call isOk() on it)
   * @param command name of the command to execute
   * @param cmdCache this string will be used to store the fully resolved
   * path and name of the command. The command given (e.g. "read_binary") will
   * be looked up internally, thereby taking into account the type of the
   * reader and the card to which the command is to be applied. If the command
   * has been found its full path will be stored in this variable. However,
   * if this string is not empty upon call this method assumes that the cache
   * already contains the full path, so it will not be looked up.
   * @param response reference to a string to receive the response
   * @param param1 first parameter to the command
   * @param param2 2nd parameter to the command
   * @param param3 3rd parameter to the command
   */
  CTError execCommand(const string &command,
		      string &cmdCache,
		      string &response,
		      const string &param1="",
		      const string &param2="",
		      const string &param3="",
		      const string &param4="",
		      const string &param5="");

  /**
   * This is the simplest form of the select file command.
   * It should work with every card.
   * @author Martin Preuss<martin@libchipcard.de>
   * @return CTError object that holds the result (call isOk() to see if
   * there was an error)
   * @param fcp a reference to a string to receive the FCI
   * @param fid the two byte file identifier
   */
  CTError selectFile(string &fcp, unsigned short fid);

  /**
   * This is the simplest form of the select file command.
   * It should work with every card.
   * @author Martin Preuss<martin@libchipcard.de>
   * @return CTError object that holds the result (call isOk() to see if
   * there was an error)
   * @param fcp a reference to a string to receive the FCI
   * @param fid file identifier
   */
  CTError selectFile(string &fcp, const string &fid);

  /**
   * Reads data from the currently selected file.
   * @author Martin Preuss<martin@libchipcard.de>
   * @param data reference to a string to receive the data
   * @param offset guess what ;-)
   * @param size how many bytes do you want to read today ?
   * @return CTError object that holds the result (call isOk() to see if
   * there was an error)
   */
  CTError readBinary(string &data,
		     unsigned int offset,
		     unsigned int size);

  CTError readBinaryRaw(string &data,
			unsigned short offset,
			unsigned char size);

  /**
   * Writes data into the currently selected file.
   * @author Martin Preuss<martin@libchipcard.de>
   * @return CTError object that holds the result (call isOk() to see if
   * there was an error)
   * @param data reference to a string to be send
   * @param offset guess what ;-) Please note that some cards do not allow
   * to write the first 26 bytes !
   * @param number of bytes to send
   */
  CTError updateBinary(const string &data,
		       unsigned int offset);


  CTError updateBinaryRaw(const string &data,
			  unsigned short offset);
  //@}
};






#endif






