************
  pcsclite  
************

:Author: Russell Stuart


.. topic:: Abstract

   The :mod:`pcsclite` package communicates with smart cards.


.. _intro:

Introduction
============

This package enables Python programs to communicate with smart cards (this
includes GSM SIM's and 3G USIM's) via a suitable reader. It is a wrapper for
the C libpcsclite library, making the functions and definitions defined by
libpcsclite available to Python programmers. It is a full and direct an
implementation, meaning if there is a function or constant defined in
libpcsclite then the same constant will appear in this module with a similar
name. Anybody who knows libpcsclite should find themselves in familiar
territory, and libpcsclite's documentation applies to this module as well. See
`Musclecard.com <http://www.musclecard.com>`_, the home page for libpcsclite,
for a copy of the libpcsclite library and its documentation.

To use this module you must have the C libpcsclite library installed and the
pcsc-lite daemon must be running.  Libpcsclite talks to the daemon, it is the
daemon that communicates with the card.

.. note::

   This module comes in Python 2 and Python 3 verions.  They are identical
   with one major exception: where Python 3 uses :class:`bytes`, Python 2 uses
   :class:`str`.  This documentation is written from the Python 3 perspective,
   so where it says :class:`bytes` for Python 2 you should substitude
   :class:`str`.  The Python modules supplied work with both Python 2 and
   Python 3.


.. _contents:

Module Contents
===============

The two major classes in the module are :class:`Context` and :class:`Card`.
These are the ones you need to focus on.   There are also several classes which
serve purely as name spaces for various constants defined :mod:`pcsclite` C
library.  Their names are spelt using all capitals.  All classes and all their
members have :attr:`__doc__` strings; even the integer and string members
have them which is somewhat unusual.

Constants defined at directly in the module are:


.. data:: INFINITE

   Passing this value to :func:`Context.get_status_change` for the timeout causes
   it to wait indefinitely.


.. data:: MAX_ATR_SIZE

   The maximum length of an attribute string handled by the functions
   :func:`Card.get_attrib` and :func:`Card.set_attrib`.


.. data:: MAX_BUFFER_SIZE_EXTENDED

   The maximum size of bytes that can be sent and received by
   :func:`Card.transmit`.


.. data:: MAX_READERNAME

   The maximum length of a card reader name returned by
   :func:`Context.list_readers`.


.. data:: PCSCLITE_MAX_READERS_CONTEXTS

   The maximum number of :class:`Context` objects that can be created.


.. _context-objects:

Context object
--------------

Context objects encapsulate a connection to the pcsc daemon. You need only one
of these.  Create it by calling the constructor. Deleting it using
:keyword:`del` will close the connection.


.. class:: Context([scope])

   The constructor creates a new connection to the pcsc daemon.   The optional
   *scope* parameter is a number, typically one of the constants defined in the
   :const:`SCOPE` object.  It defaults to :const:`SCOPE.SYSTEM`.  Throws
   :exc:`PcscliteException` if the connection to the daemon can not be created.


.. attribute:: Context.hContext

   The C libpcsclite context handle, which is an integer.  Read only.


.. attribute:: Context.scope

   The scope used to create the connection to the daemon. This is a member of
   the :const:`SCOPE` object, and as such has a :attr:`__doc__` string
   describing the scope.


.. method:: Context.cancel()

   Cancels all pending blocking requests on the
   :meth:`Context.get_status_change` function. Raises
   :exc:`PcscliteException` on failure.


.. method:: Context.connect(readername[, sharemode, protocol])

   Establish a connection to the card reader.  The first connection will
   power up and perform a reset on the card.  The parameter *readername* is a
   :class:`string` containing the name of the card reader to connect to.
   Typically you will obtain it by calling :meth:`list_readers`. The
   parameter *sharemode* says whether others can use this reader. It is an
   :class:`int`, typically one of the constants defined in the :const:`SHARE`
   object.  If omitted :const:`SHARE.SHARED` is used.  The parameter *protocol*
   specifies the protocol used to talk to the reader.  It is an :class:`int`,
   typically one of the constants defined in the :const:`PROTOCOL` object. 
   If omitted :const:`PROTOCOL.ANY` is used. A new :class:`Card` object is
   returned.  The protocol field in the returned object is set to the protocol
   established for the session. Raises :exc:`PcscliteException` on failure.


.. method:: Context.get_status_change(readers[, timeout])

   Wait for a card reader to change status, or until the timeout (given in
   seconds) expires.  If the timeout is :const:`INFINITY` or is omitted the
   method waits indefinitely.  The parameter *readers* is a sequence of
   objects that each must contain the fields *readername* and *currentstate*.
   The field *readername* is a :class:`string` containing the name of a reader
   you want to wait for a state change on, and the field *currentstate* is the
   current state (a bitwise or of members of the :const:`STATE` object)
   of that reader.  The class :class:`CardStatus` is a convenient way of
   creating a suitable object. The function returns when one of the readers
   states is different to that passed in *currentstate*.  The return value is
   a new list of :class:`CardStatus` objects, one for each *readername* passed.
   In addition to the original *readername* and *currentstate* fields these
   objects have *eventstate* and *answertoreset* fields. The *eventstate*
   contains the new state of the reader, and answertoreset field contains its
   answer to reset string sent by the card. If readers is :const:`None` the
   function returns as soon as a card reader becomes available.  Raises
   :exc:`PcscliteException` on failure.


.. method:: Context.is_valid_context()

   Returns :const:`True` if the smart card context handle is still valid.
   Raises :exc:`PcscliteException` otherwise.


.. method:: Context.list_readers([groups])

   Returns a list of currently the names available readers the daemon is
   connected to.  If the list groups is passed then only readers in those
   reader group names it contains are returned. Raises
   :exc:`PcscliteException` on failure.


.. method:: Context.list_reader_groups()

   Returns a list of currently available reader group names on the system. A
   reader group name is a :class:`string`. Raises :exc:`PcscliteException` on
   failure.


.. _card-objects:

Card object
-----------

Card objects encapsulate a connection to a particular card. They are created
by calling :func:`Context.connect`. Deleting a Card object using
:keyword:`del` will close the connection to the card.


.. attribute:: Card.context

   The :class:`Context` object that created this card.  Read only.


.. attribute:: Card.hCard

   The C libpcsclite card handle, which is an integer.  Read only.


.. attribute:: Card.protocol

   The protocol established for the session. This is a member of the
   :const:`PROTOCOL` object, and as such as a :attr:`__doc__` string
   describing the protocol. Read only.


.. attribute:: Card.readername

   The *readername* passed to :func:`Context.connect`, which is a
   :class:`string`.  Read only.


.. attribute:: Card.share

   The share mode used to create the connection. This is a member of the
   :const:`SHARE` object, and as such as a :attr:`__doc__` string
   describing the share mode. Read only.


.. method:: Card.begin_transaction()

   Establish a temporary exclusive access mode to the card for doing a series of
   commands or a transaction. Raises :exc:`PcscliteException` on failure.

.. method:: Card.control(code, data)

   Sends a command directly to the reader. This is useful for creating client
   side reader drivers for functions like PIN pads, biometrics, or other
   extensions to the normal smart card reader that are not normally handled by
   :mod:`pcsclite`.  Both *code* and *data* are :class:`bytes` containing
   the raw data to be sent to the card. Returns the reply from the card as a
   *bytes*. Raises :exc:`PcscliteException` on failure.


.. method:: Card.disconnect([disposition])

   Disconnect from the card.  The parameter *disposition* describes what state
   the card is to be left in on disconnection.  It is an :class:`int`, and is
   typically one of the constants defined by the :const:`DISPOSITION` object.
   If not passed :const:`DISPOSITION.LEAVE_CARD` is used. Raises
   :exc:`PcscliteException` on failure.


.. method:: Card.end_transaction([disposition])

   End a transaction previously begun with :func:`Card.begin_transaction`. The
   parameter *disposition* describes what state the card is to be left in on
   disconnection.  It is an :class:`int`, and is typically one of the constants
   defined by the :const:`DISPOSITION` object.  If not passed
   :const:`DISPOSITION.LEAVE_CARD` is used.  Raises :exc:`PcscliteException` on
   failure.


.. method:: Card.get_attrib(attrib)

   Get an attribute.  The current value of the attribute is returned. It is a
   :class:`string`. The parameter attrib is an :class:`int` naming the
   attribute to get. It is typically one of constants defined by the
   :const:`ATTR` object. Raises :exc:`PcscliteException` on failure.


.. method:: Card.reconnect([sharemode, protocol, disposition])

   Reconnect to a card, typically done when call to transmit() raises a
   :exc:`PcscliteException` with :const:`ERROR.RESET_CARD`. This is caused by
   another application resetting the card while you are using it.  This is
   function effectively does a :func:`Card.disconnect(disposition)` followed
   by :func:`Context.connect(oldreadername, sharemode, protocol)`. The
   *sharemode* and *protocol* default to what was last passed to
   :func:`Context.connect`.  The parameter *disposition* defaults to
   :const:`DISPOSITION.RESET_CARD` if not supplied. Raises
   :exc:`PcscliteException` on failure.


.. method:: Card.set_attrib(attrib, value)

   Set an attribute to the :class:`string` *value*. The parameter *attrib* is
   an :class:`int` naming the attribute to set. It is typically one constants
   defined by the :const:`ATTR` object. Raises :exc:`PcscliteException` on
   failure.


.. method:: Card.status()

   Get the current status of the reader. Returns a :class:`CardStatus` object
   that has these members:

   +-----------------+--------------------------------------------+
   | Field name      | Usage                                      |
   +=================+============================================+
   | *readername*    | The name of the reader, a :class:`string`. |
   +-----------------+--------------------------------------------+
   | *status*        | One of the constants defined by the        |
   |                 | :const:`STATUS` object.                    |
   +-----------------+--------------------------------------------+
   | *protocol*      | One of the constants defined by the        |
   |                 | :const:`PROTOCOL` object.                  |
   +-----------------+--------------------------------------------+
   | *answertoreset* | The card's reply when it was reset, a      |
   |                 | :class:`string`.                           |
   +-----------------+--------------------------------------------+

   Raises :exc:`PcscliteException` on failure.


.. method:: Card.transmit(data[, protocol])

   Sends the APDU (Application Protocol Data Unit) contained in the
   :class:`bytes` *data* to the smart card.  The *protocol* parameter
   specifies the protocol used to send the data.  It is an :class:`int`,
   typically one of the the constants defined by the :const:`PROTOCOL`
   object.  If not specified the protocol established by
   :func:`Context.connect` is used.  The return value is the response
   from card, which is a a subclass of :class:`bytes`. The bytes are
   the response, but the object has one additional member called *protocol*
   which is the protocol used to send the response. It is one of the
   constants defined by the :const:`PROTOCOL` object. Raises
   :exc:`PcscliteException` on failure.


.. _cardstatus-objects:

CardStatus object
-----------------

Instances of this class describe the status of a smart card. There is nothing
special about instances of this class, any other object with the same fields
will work as well. Not all fields are required and they aren't always present,
it depends on how the object is being used.


.. class:: CardStatus([readername, currentstate])

   If present, the parameters *readername* and *currentstate* are used to
   initialise the fields of the same name.


.. attribute:: CardStatus.answertoreset

   The smart card's answer when it was reset.  A :class:`bytes`. This field
   is set by :func:`Context.get_status_change`.


.. attribute:: CardStatus.currentstate

   The current state of the smart card reader.  This is a bitwise or or the
   constants defined in the :const:`STATE` object.


.. attribute:: CardStatus.eventstate

   The new state of the smart card reader.  This is a bitwise or or the
   constants defined in the :const:`STATE` object. This field is set by
   :func:`Context.get_status_change`.


.. attribute:: CardStatus.protocol

   The protocol used by the smart card when it was reset. This will be one
   of the constants defined by the :const:`PROTOCOL` object. This field is
   set by :func:`Context.get_status_change`.


.. attribute:: CardStatus.readername

   The name of a smart card reader.  A :class:`string`.


.. attribute:: CardStatus.status

   The current status of the smart card. This will be one of the constants
   defined by the :const:`STATUS` object. This field is set by
   :func:`Context.get_status_change`.


.. _pcscliteexception-objects:

PcscliteException object
------------------------

The  exception is a subclass of :exc:`StandardError`.  It is raised by all
methods defined in :mod:`pcsclite` when an error occurs.  When raised by
:mod:`pcsclite` it has one additional field:


.. attribute:: PcscliteException.scard_error

   The :class:`int` error code returned by the C libpcsclite function. This
   will be a constant defined by the :const:`ERROR` object. Like all
   constants defined in this module the error code will have a
   :attr:`__doc__` string describing what the error is.


.. _constant-objects:

Objects defining constants
--------------------------

The C libpcsclite library defines many constants which are exposed via the
objects described here.  All fields of all objects here are read only.  They
also all have a :attr:`__doc__` string describing what the are used for.


.. data:: ATTR

   This object holds constants that describe card attributes libpcsclite
   supports.  They are passed to :func:`Card.set_attrib` and
   :func:`Card.get_attrib`. Members are:

   +-----------------------------------+-------------+
   | Constant Name                     | Description |
   +===================================+=============+
   | :const:`ASYNC_PROTOCOL_TYPES`     | -           |
   +-----------------------------------+-------------+
   | :const:`ATR_STRING`               | -           |
   +-----------------------------------+-------------+
   | :const:`CHANNEL_ID`               | -           |
   +-----------------------------------+-------------+
   | :const:`CHARACTERISTICS`          | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_BWT`              | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_CLK`              | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_CWT`              | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_D`                | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_EBC_ENCODING`     | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_F`                | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_IFSC`             | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_IFSD`             | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_IO_STATE`         | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_N`                | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_PROTOCOL_TYPE`    | -           |
   +-----------------------------------+-------------+
   | :const:`CURRENT_W`                | -           |
   +-----------------------------------+-------------+
   | :const:`DEFAULT_CLK`              | -           |
   +-----------------------------------+-------------+
   | :const:`DEFAULT_DATA_RATE`        | -           |
   +-----------------------------------+-------------+
   | :const:`DEVICE_FRIENDLY_NAME_A`   | -           |
   +-----------------------------------+-------------+
   | :const:`DEVICE_FRIENDLY_NAME`     | -           |
   +-----------------------------------+-------------+
   | :const:`DEVICE_FRIENDLY_NAME_W`   | -           |
   +-----------------------------------+-------------+
   | :const:`DEVICE_IN_USE`            | -           |
   +-----------------------------------+-------------+
   | :const:`DEVICE_SYSTEM_NAME_A`     | -           |
   +-----------------------------------+-------------+
   | :const:`DEVICE_SYSTEM_NAME`       | -           |
   +-----------------------------------+-------------+
   | :const:`DEVICE_SYSTEM_NAME_W`     | -           |
   +-----------------------------------+-------------+
   | :const:`DEVICE_UNIT`              | -           |
   +-----------------------------------+-------------+
   | :const:`ESC_AUTHREQUEST`          | -           |
   +-----------------------------------+-------------+
   | :const:`ESC_CANCEL`               | -           |
   +-----------------------------------+-------------+
   | :const:`ESC_RESET`                | -           |
   +-----------------------------------+-------------+
   | :const:`EXTENDED_BWT`             | -           |
   +-----------------------------------+-------------+
   | :const:`ICC_INTERFACE_STATUS`     | -           |
   +-----------------------------------+-------------+
   | :const:`ICC_PRESENCE`             | -           |
   +-----------------------------------+-------------+
   | :const:`ICC_TYPE_PER_ATR`         | -           |
   +-----------------------------------+-------------+
   | :const:`MAX_CLK`                  | -           |
   +-----------------------------------+-------------+
   | :const:`MAX_DATA_RATE`            | -           |
   +-----------------------------------+-------------+
   | :const:`MAX_IFSD`                 | -           |
   +-----------------------------------+-------------+
   | :const:`MAXINPUT`                 | -           |
   +-----------------------------------+-------------+
   | :const:`POWER_MGMT_SUPPORT`       | -           |
   +-----------------------------------+-------------+
   | :const:`SUPRESS_T1_IFS_REQUEST`   | -           |
   +-----------------------------------+-------------+
   | :const:`SYNC_PROTOCOL_TYPES`      | -           |
   +-----------------------------------+-------------+
   | :const:`USER_AUTH_INPUT_DEVICE`   | -           |
   +-----------------------------------+-------------+
   | :const:`USER_TO_CARD_AUTH_DEVICE` | -           |
   +-----------------------------------+-------------+
   | :const:`VENDOR_IFD_SERIAL_NO`     | -           |
   +-----------------------------------+-------------+
   | :const:`VENDOR_IFD_TYPE`          | -           |
   +-----------------------------------+-------------+
   | :const:`VENDOR_IFD_VERSION`       | -           |
   +-----------------------------------+-------------+
   | :const:`VENDOR_NAME`              | -           |
   +-----------------------------------+-------------+


.. data:: ATTRCLASS

   The object holds constants that describe the classttribute
   defined in :const:`ATTR`. Members are:

   +-------------------------+---------------------------------------+
   | Constant Name           | Description                           |
   +=========================+=======================================+
   | :const:`COMMUNICATIONS` | Communication definitions             |
   +-------------------------+---------------------------------------+
   | :const:`ICC_STATE`      | ICC State specific definitions        |
   +-------------------------+---------------------------------------+
   | :const:`IFD_PROTOCOL`   | Interface Device Protocol options     |
   +-------------------------+---------------------------------------+
   | :const:`MECHANICAL`     | Mechanical characteristic definitions |
   +-------------------------+---------------------------------------+
   | :const:`POWER_MGMT`     | Power Management definitions          |
   +-------------------------+---------------------------------------+
   | :const:`PROTOCOL`       | Protocol definitions                  |
   +-------------------------+---------------------------------------+
   | :const:`SECURITY`       | Security Assurance definitions        |
   +-------------------------+---------------------------------------+
   | :const:`SYSTEM`         | System-specific definitions           |
   +-------------------------+---------------------------------------+
   | :const:`VENDOR_DEFINED` | Vendor specific definitions           |
   +-------------------------+---------------------------------------+
   | :const:`VENDOR_INFO`    | Vendor information definitions        |
   +-------------------------+---------------------------------------+


.. data:: DISPOSITION

   This object holds constants that describe what to do with a card when the
   connection to it is closed.  They are passed to :func:`Card.disconnect`,
   :func:`Card.end_transaction` and :func:`Card.reconnect`. Members are:

   +-----------------------+-------------+
   | Constant Name         | Description |
   +=======================+=============+
   | :const:`EJECT_CARD`   | Eject Card  |
   +-----------------------+-------------+
   | :const:`LEAVE_CARD`   | Do nothing  |
   +-----------------------+-------------+
   | :const:`RESET_CARD`   | Reset Card  |
   +-----------------------+-------------+
   | :const:`UNPOWER_CARD` | Power down  |
   +-----------------------+-------------+


.. data:: ERROR

   This object holds the error codes returned by the C libpcsclite library. The
   *scard_error* field of :exc:`PcscliteException` will contain one of these.
   Members are:

   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | Constant Name                   | Description                                                                                      |
   +=================================+==================================================================================================+
   | :const:`SUCCESS`                | No error was encountered                                                                         |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`BAD_SEEK`               | There was an error trying to set the smart card file object pointer                              |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`CANCELLED_BY_USER`      | The user pressed "Cancel" on a Smart Card Selection Dialog                                       |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`CANCELLED`              | The action was cancelled by an SCardCancel request                                               |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`CANT_DISPOSE`           | The system could not dispose of the media in the requested manner                                |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`CARD_NOT_AUTHENTICATED` | No PIN was presented to the smart card                                                           |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`CARD_UNSUPPORTED`       | The smart card does not meet minimal requirements for support                                    |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`CERTIFICATE_UNAVAILABLE`| The requested certificate could not be obtained                                                  |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`CHV_BLOCKED`            | The card cannot be accessed because the maximum number of PIN entry attempts has been reached    |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`COMM_DATA_LOST`         | A communications error with the smart card has been detected. Retry the operation                |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`COMM_ERROR`             | An internal communications error has been detected                                               |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`DIR_NOT_FOUND`          | The identified directory does not exist in the smart card                                        |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`DUPLICATE_READER`       | The reader driver did not produce a unique reader name                                           |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`EOF`                    | The end of the smart card file has been reached                                                  |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`FILE_NOT_FOUND`         | The identified file does not exist in the smart card                                             |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`ICC_CREATEORDER`        | The requested order of object creation is not supported                                          |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`ICC_INSTALLATION`       | No primary provider can be found for the smart card                                              |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`INSERTED_CARD`          | Not Documented in PC/SC Lite                                                                     |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`INSUFFICIENT_BUFFER`    | The data buffer to receive returned data is too small for the returned data                      |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`INTERNAL_ERROR`         | An internal consistency check failed                                                             |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`INVALID_ATR`            | An ATR obtained from the registry is not a valid ATR string                                      |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`INVALID_CHV`            | The supplied PIN is incorrect                                                                    |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`INVALID_HANDLE`         | The supplied handle was invalid                                                                  |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`INVALID_PARAMETER`      | One or more of the supplied parameters could not be properly interpreted                         |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`INVALID_TARGET`         | Registry startup information is missing or invalid                                               |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`INVALID_VALUE`          | One or more of the supplied parameters values could not be properly interpreted                  |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NO_ACCESS`              | Access is denied to this file                                                                    |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NO_DIR`                 | The supplied path does not represent a smart card directory                                      |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NO_FILE`                | The supplied path does not represent a smart card file                                           |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NO_KEY_CONTAINER`       | The requested key container does not exist on the smart card                                     |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NO_MEMORY`              | Not enough memory available to complete this command                                             |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NO_READERS_AVAILABLE`   | Cannot find a smart card reader                                                                  |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NO_SERVICE`             | The Smart card resource manager is not running                                                   |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NO_SMARTCARD`           | The operation requires a Smart Card, but no Smart Card is currently in the device                |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NO_SUCH_CERTIFICATE`    | The requested certificate does not exist                                                         |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NOT_READY`              | The reader or smart card is not ready to accept commands                                         |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`NOT_TRANSACTED`         | An attempt was made to end a non-existent transaction                                            |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`PCI_TOO_SMALL`          | The PCI Receive buffer was too small                                                             |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`PROTO_MISMATCH`         | The requested protocols are incompatible with the protocol currently in use with the smart card  |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`READER_UNAVAILABLE`     | The specified reader is not currently available for use                                          |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`READER_UNSUPPORTED`     | The reader driver does not meet minimal requirements for support                                 |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`REMOVED_CARD`           | The smart card has been removed, so further communication is not possible                        |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`RESET_CARD`             | The smart card has been reset, so any shared state information is invalid                        |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`SECURITY_VIOLATION`     | Access was denied because of a security violation                                                |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`SERVER_TOO_BUSY`        | The Smart Card Resource Manager is too busy to complete this operation                           |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`SERVICE_STOPPED`        | The Smart card resource manager has shut down                                                    |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`SHARING_VIOLATION`      | The smart card cannot be accessed because of other connections outstanding                       |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`SHUTDOWN`               | The operation has been aborted to allow the server application to exit                           |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`SYSTEM_CANCELLED`       | The action was cancelled by the system, presumably to log off or shut down                       |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`TIMEOUT`                | The user-specified timeout value has expired                                                     |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`UNEXPECTED`             | An unexpected card error has occurred                                                            |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`UNKNOWN_CARD`           | The specified smart card name is not recognized                                                  |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`UNKNOWN_ERROR`          | An internal error has been detected, but the source is unknown                                   |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`UNKNOWN_READER`         | The specified reader name is not recognized                                                      |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`UNKNOWN_RES_MNG`        | An unrecognized error code was returned from a layered component                                 |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`UNPOWERED_CARD`         | Power has been removed from the smart card, so that further communication is not possible        |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`UNRESPONSIVE_CARD`      | The smart card is not responding to a reset                                                      |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`UNSUPPORTED_CARD`       | The reader cannot communicate with the card, due to ATR string configuration conflicts           |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`UNSUPPORTED_FEATURE`    | Feature not supported                                                                            |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`WAITED_TOO_LONG`        | An internal consistency timer has expired                                                        |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`WRITE_TOO_MANY`         | The smart card does not have enough memory to store the information                              |
   +---------------------------------+--------------------------------------------------------------------------------------------------+
   | :const:`WRONG_CHV`              | The card cannot be accessed because the wrong PIN was presented                                  |
   +---------------------------------+--------------------------------------------------------------------------------------------------+


.. data:: FEATURES

   This object defines TeleTrust Class 2 reader tags. Members are:

   +-----------------------------------+--------------------------------+
   | Constant Name                     | Description                    |
   +===================================+================================+
   | :const:`ABORT`                    | SCM Proposal                   |
   +-----------------------------------+--------------------------------+
   | :const:`CCID_ESC_COMMAND`         | CCID control command           |
   +-----------------------------------+--------------------------------+
   | :const:`EXECUTE_PACE`             | Supports PACE protocol         |
   +-----------------------------------+--------------------------------+
   | :const:`GET_KEY`                  | OMNIKEY Proposal               |
   +-----------------------------------+--------------------------------+
   | :const:`GET_KEY_PRESSED`          | OMNIKEY Proposal               |
   +-----------------------------------+--------------------------------+
   | :const:`GET_TLV_PROPERTIES`       | TLV version of properties      |
   +-----------------------------------+--------------------------------+
   | :const:`IFD_DISPLAY_PROPERTIES`   | Gemplus Proposal               |
   +-----------------------------------+--------------------------------+
   | :const:`IFD_PIN_PROPERTIES`       | Gemplus Proposal               |
   +-----------------------------------+--------------------------------+
   | :const:`MCT_READER_DIRECT`        | KOBIL Proposal                 |
   +-----------------------------------+--------------------------------+
   | :const:`MCT_UNIVERSAL`            | KOBIL Proposal                 |
   +-----------------------------------+--------------------------------+
   | :const:`MODIFY_PIN_DIRECT`        | USB CCID PIN Modify            |
   +-----------------------------------+--------------------------------+
   | :const:`MODIFY_PIN_DIRECT_APP_ID` | USB CCID PIN Modify            |
   +-----------------------------------+--------------------------------+
   | :const:`MODIFY_PIN_FINISH`        | OMNIKEY Proposal               |
   +-----------------------------------+--------------------------------+
   | :const:`MODIFY_PIN_START`         | OMNIKEY Proposal               |
   +-----------------------------------+--------------------------------+
   | :const:`SET_SPE_MESSAGE`          | Message displayed during SPE   |
   +-----------------------------------+--------------------------------+
   | :const:`VERIFY_PIN_DIRECT`        | USB CCID PIN Verify            |
   +-----------------------------------+--------------------------------+
   | :const:`VERIFY_PIN_DIRECT_APP_ID` | USB CCID PIN Verify            |
   +-----------------------------------+--------------------------------+
   | :const:`VERIFY_PIN_FINISH`        | OMNIKEY Proposal               |
   +-----------------------------------+--------------------------------+
   | :const:`VERIFY_PIN_START`         | OMNIKEY Proposal               |
   +-----------------------------------+--------------------------------+
   | :const:`WRITE_DISPLAY`            | Write UTF8 message to display  |
   +-----------------------------------+--------------------------------+


.. data:: FEATURE_PROPS

   Information returned by :data:`FEATURE`.GET_TLV_PROPERTIES

   +--------------------------+-----------------------------------------+
   | Constant Name            | Description                             |
   +==========================+=========================================+
   | EntryValidationCondition | When PIN entry is considered complete   |
   +--------------------------+-----------------------------------------+
   | FirmwareID               | UTF8 Reader Firmware String             |
   +--------------------------+-----------------------------------------+
   | LcdLayout                | Display characteristics                 |
   +--------------------------+-----------------------------------------+
   | LcdMaxCharacters         | Max chars on a single line.             |
   +--------------------------+-----------------------------------------+
   | LcdMaxLines              | Lines on the display                    |
   +--------------------------+-----------------------------------------+
   | MaxPINSize               | Maximum PIN size accepted by the reader |
   +--------------------------+-----------------------------------------+
   | MinPINSize               | Minimum PIN size accepted by the reader |
   +--------------------------+-----------------------------------------+
   | PPDUSupport              | How PPDU is implemented                 |
   +--------------------------+-----------------------------------------+
   | TimeOut2                 | Timeout in secs after 1st key stroke    |
   +--------------------------+-----------------------------------------+


.. data:: PROTOCOL

   This object holds constants that describe the protocols that can be used to
   communicate with a smart card.  These *int*'s form a bit map. Members are:

   +----------------+---------------------+
   | Constant Name  | Description         |
   +================+=====================+
   | :const:`ANY`   | Protocol T=0 or T=1 |
   +----------------+---------------------+
   | :const:`RAW`   | Protocol RAW        |
   +----------------+---------------------+
   | :const:`T0`    | Protocol T=0        |
   +----------------+---------------------+
   | :const:`T15`   | Protocol T=15       |
   +----------------+---------------------+
   | :const:`T1`    | Protocol T=1        |
   +----------------+---------------------+
   | :const:`UNSET` | Protocol not set    |
   +----------------+---------------------+


.. data:: SCOPE

   This object holds constants that define what scope a connection to the
   libpcsclite daemon.  They are passed to the constructor of :class:`Context`.
   Members are:

   +-------------------+---------------------+
   | Constant Name     | Description         |
   +===================+=====================+
   | :const:`SYSTEM`   | scope in system     |
   +-------------------+---------------------+
   | :const:`TERMINAL` | scope in terminal   |
   +-------------------+---------------------+
   | :const:`USER`     | scope in user space |
   +-------------------+---------------------+


.. data:: SHARE

   This object holds constants that describe who else may use a card reader
   while this context is attached to it.  They are passed to
   :func:`Context.connect` and :func:`Card.reconnect`. Members are:

   +--------------------+--------------------------------------------+
   | Constant Name      | Description                                |
   +====================+============================================+
   | :const:`DIRECT`    | Direct control of reader, no card required |
   +--------------------+--------------------------------------------+
   | :const:`EXCLUSIVE` | No others may share reader                 |
   +--------------------+--------------------------------------------+
   | :const:`SHARED`    | Reader may be shared with others           |
   +--------------------+--------------------------------------------+


.. data:: STATE

   This object holds constants that describe what the current state of a card
   reader and the card in it.  The constants form a bit map, so actual values
   may be a logical or'ing of the ones shown here. The constants are passed
   to and returned by :func:`Context.get_status_change`. Members are:

   +----------------------+--------------------+
   | Constant Name        | Description        |
   +======================+====================+
   | :const:`ATRMATCH`    | ATR matches card   |
   +----------------------+--------------------+
   | :const:`CHANGED`     | State has changed  |
   +----------------------+--------------------+
   | :const:`EMPTY`       | Card removed       |
   +----------------------+--------------------+
   | :const:`EXCLUSIVE`   | Exclusive Mode     |
   +----------------------+--------------------+
   | :const:`IGNORE`      | Ignore this reader |
   +----------------------+--------------------+
   | :const:`INUSE`       | Shared Mode        |
   +----------------------+--------------------+
   | :const:`MUTE`        | Unresponsive card  |
   +----------------------+--------------------+
   | :const:`PRESENT`     | Card inserted      |
   +----------------------+--------------------+
   | :const:`UNAVAILABLE` | State unavailable  |
   +----------------------+--------------------+
   | :const:`UNAWARE`     | App wants status   |
   +----------------------+--------------------+
   | :const:`UNKNOWN`     | Reader unknown     |
   +----------------------+--------------------+
   | :const:`UNPOWERED`   | Unpowered card     |
   +----------------------+--------------------+


.. data:: STATUS

   This object holds constants that describe what a card's current status is.
   The are returned by :func:`Card.status`. Members are:

   +---------------------+-----------------------------+
   | Constant Name       | Description                 |
   +=====================+=============================+
   | :const:`ABSENT`     | Card is absent              |
   +---------------------+-----------------------------+
   | :const:`NEGOTIABLE` | Card is ready for PTS       |
   +---------------------+-----------------------------+
   | :const:`POWERED`    | Card is powered             |
   +---------------------+-----------------------------+
   | :const:`PRESENT`    | Card is present             |
   +---------------------+-----------------------------+
   | :const:`SPECIFIC`   | Card has been sent PTS      |
   +---------------------+-----------------------------+
   | :const:`SWALLOWED`  | Card not powered            |
   +---------------------+-----------------------------+
   | :const:`UNKNOWN`    | Card is in an unknown state |
   +---------------------+-----------------------------+


Example
=======

This example selects the MF, illustrating how to use the library::

   >>> import pcsclite, binascii
   >>> context = pcsclite.Context()
   >>> readers = context.list_readers()
   >>> readers
   ('OmniKey CardMan 6121 00 00',)
   >>> card = context.connect(readers[0])
   >>> card.reconnect()
   >>> response = card.transmit(b'\x00\xa4\x00\x04\x02\x3f\x00')
   >>> binascii.b2a_hex(response)
   b'615a'
   >>> data = card.transmit(b'\x00\xc0\x00\x00' + response[-1])
   >>> binascii.b2a_hex(data[-10:])
   b'018181040001dbcc9000'
   >>> data.protocol
   0L
   >>> data.protocol.__doc__
   'Protocol is not set'
   >>> del card; del context

Point of interest are:

:samp:`context = pcsclite.Context()`
  This object is the connection to the pcsc daemon. You need one of
  these.  If this or any other call to libpcsclite fails a
  :exc:`PcscliteException` is raised.  You use this object to do things to
  cards: connect to them, list them, wait for one to be available and so on.

:samp:`readers = context.list_readers()`
  This is a list of smart card readers the daemon knows about.

:samp:`card = context.connect(readers[0])`
  The call :func:`Context.connect` creates a connection to a particular
  card. It is encapsulated in the returned :class:`Card` object.

:samp:`card.reconnect()`
  The call :func:`Card.reconnect` resets the card to a known
  state. Not always required, but good practice.

:samp:`response = card.transmit(b'\x00\xa4\x00\x04\x02\x3f\x00')`
  The :func:`Card.transmit` method sends an APDU (which is smart card
  speak for a "command") to the card and returns the response.  There is a
  standard set of APDU's defined by the ISO 7816 standard, however most smarts
  card implement only part of the standard and add extensions.  Both the APDU
  and the response are ASCII strings.  The APDU transmitted here works with
  ISO 7816 cards; it asks the card to send what it knows about the file 3f00.
  In smart card parlance this is known as "MF", the root directory of the file
  system.  The GSM version of the same command is
  ``b'\xa0\xa4\x00\x00\x02\x3f\x00'``. A smart card always sends back a
  response to each command and that response is returned by
  :func:`Card.transmit`.  The last two bytes of the response are called the
  "status words".  Any additional data returned by the command prefixes those
  status words.  The meaning of the status words is defined in *ISO 7816-4*.
  The response seen here, 615a, means the call worked and there is 0x5a bytes
  of data is waiting to be fetched.  Since there is only 2 bytes returned
  there is no additional data.

:samp:`data = card.transmit(b'\x00\xc0\x00\x00' + response[-1])`
  The second call to :func:`Card.transmit` asks the card to send the
  waiting data.  As before, the last two bytes of the response are the status
  words.  In this case they are 9000 which ISO 7816-4 defines to mean the
  command was successful.  The remaining bytes are the data generated by the
  previous command.  In this case they contain information about the MF.
  The format of that information is defined in ISO 7816-4.

:samp:`data.protocol`
  Although the result returned by :func:`Card.transmit` looks like
  a :class:`string` and indeed is a subclass of :class:`string`, it contains
  an extra field called *protocol* which is the protocol used to send the
  response.  This field is filled in by the smart card reader driver.   The
  protocol constants are defined in the object :const:`PROTOCOL`.

:samp:`data.protocol.__doc__`
  To find out what protocol ``0L`` is you could look up the :const:`PROTOCOL`
  object. But if is it a known protocol it will have a :attr:`__doc__` string.
  In this case it looks like the pcsc-lite driver hasn't set the field.
  Every numerical constant defined by this module has a :attr:`__doc__`
  string.

:keyword:`del`
  When the card object is deleted its connection to the card is released.
  Similarly when a context is deleted (assuming there are no cards holding
  references to it) the connection to the daemon is closed.

Installation and Configuration
==============================

To compile you need :mod:`pcsclite` you need the GNU C tool chain, the Python
development system and libpcsclite.  Then its just a case of running make.

To install put the resulting pcsclite.so somewhere in Python's :data:`sys.path`.

There is no configuration required for :mod:`pcsclite`, but the pcsc-lite
library and daemon may need some tweaking. Refer to its documentation.

When it comes to hardware, `<http://www.muscelcard.com>`_ has a list of smart
card readers that work with pcsc-lite. That said, the world is moving to USB.
The USB protocol used to talk to a smart card readers has been standardised.
It is called CCID. Pcsc-lite supports CCID USB smart card readers out of the
box.  No configuration is required. The reader just appears in the
:func:`Context.list_readers` when it plugged into the USB port.


Other sources of Information
============================

The main reference for smart card standards are the  `International Standards
Organisation <http://www.iso.org>`_ *ISO 7816* series, and in particular *ISO
7816-4* and *ISO 7816-9*. Unfortunately these documents are not free. However,
there are cut down versions available on the web which are good enough for most
purposes.  I found this link by googling "7816 standards":
`<http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816.aspx>`_.

The major application for smart cards is GSM and its successors. The
documentation for these cards is published by `3gpp <http://www.3gpp.org>`_.
They are free and available on the web. The original GSM standard is called
*GSM 11.11*. Googling for that string will find it. GSM SIM's pre-date
ISO 7816-4, so with the release of 3G the 3gpp decided to update the GSM SIM
to something that followed 7618-4 a little more closely.  The end result is
called a USIM.  7618-4 cards can contain several directory trees (think C:,
D:, etc under Windows), although in 7618 parlance these are trees are
called applications. The default tree contains the original GSM application,
so *GSM 11.11* still applies to USIM's.  USIM's however contain another
application, the 3G one.  This is defined in the 3gpp standards *TS 31.101*
and *TS 31.102*. Again googling for those strings will find them. The
`European Telecommunications Standards Institute <http://www.etsi.org>`_
publishes a lot of the 3gpp standards under their own banner, again for free.
The most relevant ETSI standard is `TS 102 221 <https://www.etsi.org/deliver/etsi_ts/102200_102299/102221/16.05.00_60/ts_102221v160500p.pdf>`_.

The canonical book for smart cards is the *Smart Card Handbook*, by *Wolfgang
Ranki* and *Wolfgang Effing*.  It is probably required reading for someone
designing a smart card application, but for the typical user of this library I
don't think covers any useful material that isn't available in the links above.

One thing that is hard to find on the web is the contents of *ISO 7816-9*,
which covers the smart card security system. The closest you will get to it is
documentation from smart card manufacturers describing whatever bit they deem
interesting. Collect enough bits and you will have the entire thing.

Finally, shipped with this module are two Python examples. The file
:file:`iso7816.py` contains definitions relating to ISO 7816-4, some ISO 7816-9,
GSM and USIM cards. For example, it decodes the response an a SELECT APDU,
documents the GSM and USIM directory trees, and can pretty print most of the
files found in those trees. The program :file:`usimtool.py` uses iso7816.py and
this module to manipulate GSM, ISO 7816 and USIM cards.  It can search the
entire directory tree, pretty printing files iso7618 knows about, enter and
change pins and so on. Run usimtool.py without any arguments to get a list of
commands it supports. These two files aren't supported in any way but do serve
as useful examples.


The usimtool.py program
-----------------------

This is a brief guide to :file:`usimtool.py`. :file:`usimtool.py` manipulates
GSM, USIM and ISO 7816 smart cards. :file:`usimtool.py` requires
:file:`pcsclite.so` and :file:`iso7816.py` to be in Python's :data:`sys.path`.

It is a command line tool. Commands are given on the command line separated by
spaces.   When :file:`usimtool.py` starts it searches for the first available
card reader, prints its name, connects to it and then executes the commands
given. By default commands are executed using GSM class APDU's, but this this
can be changed using *usim* command.

Many commands take or print smart card path names. The syntax used is:
**/application/fid/fid...** A *fid* is a smart card file name. Smart card file
names are 16 bit numbers, and are represented 4 hex digits. The *application*
is an Application Identifier (:dfn:`AID`) as defined in ISO 7816-4.  This is
typically a 32 digit hex number. It is used to select the starting Application
Directory File (:dfn:`ADF`). If left blank the MF is used. An AID consists of 3
parts: a vendor ID (5 bytes), followed by an application class (2 bytes)
followed by a vendor assigned name (11 bytes). I doubt too many people know the
entire AID off the top of their head, but they typically do know the application
class (eg 1002 is USIM) and possibly the vendor ID.  So as a shortcut when
specifying an AID on the command line if you specify an AID less that 32 digits
a prefix search is used. Giving up to 4 digits will match the first AID on the
card whose application class starts with the digits supplied.   Giving from 5 to
14 digits will match the first AID on the card whose application class matches
the last 4 digits supplied and the vendor ID starts with the rest. Giving more
than 14 digits matches the AID on the card that starts with the digits supplied.

Some examples of paths:

* **/** - matches the MF.

* **//2f06** - matches the file 2f06 under the MF (typicalled called EFatr in
  smart card documentation).

* **//7f10/6f3b** - matches the file 6f3b in the MF directory 7f10.

* **/a0000000871002ff47f00189000001ff** - Matches the ADF supplied.

* **/a0000000871002ff47** - Matches the same ADF as previous, assuming it is
  the first one listed in EFdir.

* **/a0000000871002** - Ditto.

* **/a01002** - Ditto.

* **/1002** - Ditto.

* **/10** - Ditto.

* **/1002/6f3c** - Matches the file 6f3c in ADF
  a0000000871002ff47f00189000001ff.

* **/1002/7f10/6f3c** - Matches the file 6f3c in the directory 7f10 under the
  same ADF.

.. note::

  When GSM class APDU's are being issued, and this is the default, an ADF
  can not be selected.  Thus in GSM mode the *application* component of the
  path must always be blank.  If not you will get an error.

Some commands print out a directory listing.  These have the following format::

   s:/1002/6f3c = 6f3c:01 EF 8800 lin P1,P1,??,P1,A4,A4 len=176:50

The format will vary a bit depending on the type of file and the class of APDU
being used, but this example illustrates the main elements.  Breaking the line
printed into its constituent bits we have:

* ``s:/1002/6f3c`` is the command that generated the listing.

* ``6f3c:01`` 6f3c is the name of the file being listed.  The short name is 01.

* ``EF`` means this is a normal data file.  ``DF`` indicates a directory file.

* ``8800`` The size of the file in bytes.

* ``lin`` The file structure is linear. Other possibilities are ``cyc=cyclic``,
  ``ctv=cyclic-tlv``, ``ltv=linear-tlv``, ``trn=transparent``,
  ``vin=linear-variable``, ``vtv=linear-variable-tlv``.

* ``P1,P1,??,P1,A4,A4`` The security level for these actions: read, update,
  increase, rfu, deactivate, activate. Security level :samp:`P{x}` means pin
  number :samp:`{x}` AW means always allowed, :samp:`N{x}` for any :samp:`{x}`
  means never allowed, :samp:`A{x}` means administrative pin :samp:`{x}`.
  The security levels are accurate when GSM class commands are being issued
  but are educated guesses for USIM class commands are being issued.

* ``len=176:50`` The record length is 176 bytes, and there are 50 records in the
  file.

Commands available:

**?, h, -h, help, --help**
  Prints a short summary of the commands available.

**hex-apdu**
  The argument is a raw APDU in hex.  Issues the APDU and prints
  the results. The APDU can have '.'s inserted for readability. ::

   usimtool.py a0a4.0000.02.3f00
   a0a4.0000.02.3f00 = 000009f83f00010000000000169305070400838a838a0003000009f8000009f8000000

**activate:path**
  Do a USIM ACTIVATE (aka GSM REHABILITATE) on *path*. ::

   usimtool.py activate://7f10/6f3a

**changeP:old,new**
  Change pin *P* from *old* to *new*. *P* can be 1 or 2.
  This works with GSM and USIM cards. ::

   usimtool.py change1:0000,1234

**deactivate:path**
  Do a USIM DEACTIVATE (aka GSM INVALIDATE) on *path*. ::

   usimtool.py deactivate://7f10/6f3a

**dir:path[,*fid*]**
  List the files in directory *path*. If the two hex digits
  *fid* is given then only files starting with that byte are printed. ::

   usimtool.py dir://7f10,6f
   dir://7f10,6f = 6f06    EF 2250 lin AW,A4,AW,AW,A4,A4 len=150:? 16:19=6f0601
   dir://7f10,6f = 6f3a    EF 9500 lin P1,P1,AW,AW,P2,P2 len=38:? life=x02 16:19=6f0605
   ...

**disableP:old**
  Disable pin *P*.  Pin *P* must have the value *old*. *P* can
  be 1 or 2. This works with GSM and USIM cards. ::

   usimtool.py disable1:1234

**enableP:new**
  Enable pin *P*, setting it to *new*. *P* can be 1 or 2. This
  works with GSM and USIM cards. ::

   usimtool.py enable1:1234

**dump:path**
  Dump the contents of file *path* in hex. ::

   usimtool.py dump:2fe2
   dump://2fe2 = 981620136045138543f2

**dumptree:path**
  Recursively dump the contents of all files under *path* in hex. ::

   usimtool.py dumptree
   dumptree:/ = 3f00    DF pins=1+2 8:12=0fffff01 18=83 23:27=8a8a8a8a
   dumptree://0002 = 00000000000000000121e6ffff000000
   ...

**gsm**
  Use GSM class APDU's (ie, class 0xa0) for the following commands, and
  reset the card.  This is the default. ::

   usimtool.py gsm

**pinP:old**
  Unlock commands requiring pin *P* using the pin *old*. *P* can be
  1 or 2. This works with GSM and USIM cards. ::

   usimtool.py pin1:1234

**print:path**
  Pretty print the file *path* if its format is known to
  :file:`iso7816.py`, otherwise dump it. ::

   usimtool.py print://7f10/6f3b
   print://7f10/6f3b[1] = {id:'Emergency', len:3., ton:80, num:+112, cap:ff, recid:ff}
   print://7f10/6f3b[2] = {id:'Emergency Aust.', len:3., ton:81, num:+000, cap:ff, recid:ff}
   print://7f10/6f3b[3] = {id:'Emergency TTY', len:3., ton:81, num:+106, cap:ff, recid:ff}
   print://7f10/6f3b[4..50] = {id:'', len:255., ton:ff, num:+, cap:ff, recid:ff}

**printtree[:*path*,...]**
  Recursively print all files under *path*. If *path* is not supplied all
  files under the MF are printed if GSM class APDU's are being
  issued. If USIM class APDU's are being issued print all files under
  all ADF's as well. ::

   usimtool.py printtree
   printtree://0002 = 06000915864700015affffffffff10
   printtree://2f00[1] = {template:61, template_len:32., tag:4f, aid_len:16., aid:a0000000871002ff47f00189000001ff, appl:[{tag:50, len:7., label:'SingTel'}]}
   printtree://2f05 = {lang:[656e, ffff, ffff, ffff, ffff]}
   printtree://2f06[1] = <SAC=01, always=, SAC=1e, or=<crt=<key=0a, action=08>, crt=<key=0b, action=08>>>
   printtree://2f06[2] = <>
   printtree://2f06[3] = <SAC=01, always=, SAC=1e, or=<crt=<key=0a, action=08>, crt=<key=0b, action=08>,crt=<key=0d, action=08>>>
   ...

**pukP:PUK,new**
  Unlock blocked pin *P* using the unlock code *PUK*, setting the pin to
  be *new*. *P* can be 1 or 2. This works with GSM and USIM cards. ::

   usimtool.py puk1:12345678,1234

**s:path**
  Issue a SELECT command for *path*. If *path* isn't absolute the
  current DF is used as a starting point. ::

   usimtool.py usim s:/1002/6f3c
   s:/1002/6f3c = 6f3c:   EF 8800 lin P1,P1,??,P1,A4,A4 len=176:50

**trace:value**
  When trace is on APDU's sent to the card and responses received are printed
  in hex.  *value* can be ``on`` or ``off``. Internal file reads are
  suppressed.  So in example below the **s** command reads EFdir and
  EFarr in order do the prefix search for the AID and to interpret the
  results of the SELECT command, but you don't see that in the trace. ::

   ./usimtool.py trace:on usim s:/1002/7f10/6f3a
   00a4040410a0000000871002ff47f00189000001ff=6144, 00c0000044=6242820278218410a0000000871002ff47f00189000001ffa5118001318103010a3282010a8304000009f88a01058b032f0619c60990014083010183018181040000178f9000
   00a40004027f10=612e, 00c000002e=622c8202782183027f10a5098001318304000009f88a01058b032f0618c60990014083010183018181040000ed679000
   00a40004026f3a=6283
   s:/1002/7f10/6f3a = : 6283 execution error, memory unchanged - selected file invalid

**tree[:*path*,...]**
  Does a recursive directory listing of all files under *path*. If *path* is
  not supplied all files under the MF are listed if GSM class APDU's are
  being issued. If USIM class APDU's are being issued lists all files under
  all ADF's as well. ::

   usimtool.py usim tree
   tree:/ = 3f00:00 DF pins=1
   tree://0002 = 0002:   EF   15 trn AW,A4,??,A4,A4,A4
   tree://2f00 = 2f00:1e EF   38 lin AW,A4,??,A4,A4,A4 len=38:1
   tree://2f05 = 2f05:05 EF   10 trn AW,P1,??,P1,A4,A4
   tree://2f06 = 2f06:06 EF 4800 lin AW,A4,??,A4,A4,A4 len=150:32
   ...
   tree:/a0000000871002ff47f00189000001ff = ?    DF pins=1 dfname=a0000000871002ff47f00189000001ff
   tree:/a0000000871002ff47f00189000001ff/2f24 = 2f24:   EF   52 lin A4,A4,??,A4,A4,A4 len=13:4
   tree:/a0000000871002ff47f00189000001ff/2f27 = 2f27:   EF  300 lin A4,A4,??,A4,A4,A4 len=6:50
   tree:/a0000000871002ff47f00189000001ff/2f28 = 2f28:   EF   11 trn A4,A4,??,A4,A4,A4
   tree:/a0000000871002ff47f00189000001ff/6f05 = 6f05:02 EF   10 trn AW,P1,??,P1,A4,A4
   ...

**update:path,recno,data**
  Update (overwrite) the data at record number *recno* in the file *path*
  with *data*. If *recno* is 0 or blank the entire file is updated, otherwise
  the specified record is updated. The *data* is a hex string possibly ending
  with ``*repeat_count``. If a ``repeat_count`` is given the last byte is
  repeated that many times. ::

   usimtool.py update://7ff0/6f56,,05

   usimtool.py update://7f10/6f3a,1,ff*37

**usim**
  Use USIM class APDU's (ie, class 0x00) for the following commands,
  and reset the card. ::

   usimtool.py usim

.. _links: