/***************************************************************************
 $RCSfile: ctprocessorcard.h,v $
                             -------------------
    cvs         : $Id: ctprocessorcard.h,v 1.6 2003/01/10 20:02:27 aquamaniac Exp $
    begin       : Wed Aug 29 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                                                   *
 *                                                                         *
 ***************************************************************************/

/*
 Changes
 2002/06/03: Martin Preuss<martin@libchipcard.de>
 - added fallback mechanism to selectXX methods. They now first try to
   execute the command intended, and if that fails they call selectFile()

 */


#ifndef CTPROCESSORCARD_H
#define CTPROCESSORCARD_H

class CTProcessorCard;


#include <string>
#include <chipcard/ctcard.h>
#include <chipcard/cterror.h>


/**
 * This class provides basic access to processor chip cards.
 * It allows reading, writing and selecting of files on the card.
 * @author Martin Preuss<martin@libchipcard.de>
 * @ingroup gcards
 * @short Basic class for processor cards
 */
class CHIPCARD_API CTProcessorCard : public CTCard {
private:
  string _cmdSelectMF;
  string _cmdSelectParent;
  string _cmdSelectDF;
  string _cmdSelectEF;
  string _cmdSelectId;
  string _cmdReadRecord;
  string _cmdUpdateRecord;

  CTError _selectMF(string &fcp);
  CTError _selectDF(string &fcp, unsigned short fid);
  CTError _selectEF(string &fcp, unsigned short fid);
  CTError _selectById(string &fcp, string id);

public:
  /** @name Constructors/Destructor
   *
   * Methods to retrieve the private members of this class.
   */
  //@{
  /**
   * Constructor. This one does no interaction with the terminal reader.
   * @author Martin Preuss<martin@libchipcard.de>
   */
  CTProcessorCard();

  /**
   *
   */
  CTProcessorCard(CTCard &c);

  virtual ~CTProcessorCard();
  //@}

  /** @name Opening and closing operations
   *
   * Methods to connect and disconnect the card. Most other methods
   * only work if the card is open.
   */
  //@{
  /**
   * 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();
  //@}

  /** @name Commands
   *
   * These methods allow you to send a command to the card. Of course the
   * card needs to be already open.
   */
  //@{
  /**
   * Selects the master file.
   * On success the FCI (File Control Information) is returned.
   * The FCI may contain some usefull information about access rights
   * you have for the file.
   * For a closer information about FCI see the file "geldkarte.pdf"
   * which may be obtained from the Chaos Computer Club (CCC).
   * Please note that some cards do not support this command. In that
   * case you have to use the basic method @ref CTCard::selectFile().
   * @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
   */
  CTError selectMF(string &fcp);

  /**
   * Selects a dedicated file (DF) within the currently selected one.
   * On success the FCI is returned.
   * Please note that some cards do not support this command. In that
   * case you have to use the basic method @ref CTCard::selectFile().
   * @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 selectDF(string &fcp, unsigned short fid);

  /**
   * Selects an elementary file (EF) within the currently selected DF.
   * On success the FCI is returned.
   * Please note that some cards do not support this command. In that
   * case you have to use the basic method @ref CTCard::selectFile().
   * @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 selectEF(string &fcp, unsigned short fid);

  /**
   * Selects the parent DF of the currently selected DF/EF.
   * On success the FCI is returned.
   * Please note that some cards do not support this command. In that
   * case you have to use the basic method @ref CTCard::selectFile().
   * @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
   */
  CTError selectParent(string &fcp);

  /**
   * Selects a DF by its name (AID, Application Identifier).
   * On success the FCI is returned.
   * Please note that some cards do not support this command. In that
   * case you have to use the basic method @ref CTCard::selectFile().
   * @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 id file identifier
   */
  CTError selectById(string &fcp, string id);

  /**
   * Reads a record from the currently selected EF.
   * @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 receive the data
   * @param num number of the record to retrieve. Please note that
   * the first record has the number 1, because 00 and 0xff are reserved !!
   * @param size number of bytes to read (if 0 or omitted all bytes are read)
   */
  CTError readRecord(string &data,
		     unsigned char num,
		     unsigned char size=0);

  /**
   * Writes a record into the currently selected EF.
   * @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 which holds the data to be written
   * @param num number of the record to write to. Please note that
   * the first record has the number 1, because 00 and 0xff are reserved !!
   */
  CTError updateRecord(string &data,
		       unsigned char num);
  //@}


};







#endif













