/*************************************************************************** $RCSfile: tutorial2.cpp,v $ ------------------- cvs : $Id: tutorial2.cpp,v 1.3 2003/05/08 12:50:50 aquamaniac Exp $ begin : Sun Nov 18 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 * * * ***************************************************************************/ /* * This is a small tutorial on how to use the basic functions of the * libchipcard. It just determines whether an inserted card is a processor * or a memory card. * This is the most basic type of application using a chipcard, no error * checking is performed. * This tutorial is intended to show the basics only. * After studying this tutorial you should advance to the next one, which * introduces error checking. * * Usage: * tutorial2 */ #include // you need only the following include #include "chipcard.h" int main(int argc,char **argv) { /* ------------------------------------------------------------------------ * CTCard is the most important class of Libchipcard. All card classes are * derived from this base class. * You can not create a CTCard class yourself, you must use another class * for this: CTCardTrader (see below). */ CTCard *card; /* ------------------------------------------------------------------------ * A CTCardTrader is a class which basically creates CTCard objects. * However, this class does not simply create such an object. It is used * to tell Libchipcard what kind of card we want to use. * * Basically there are two types of chipcards: * - memory cards (used to store data only) * - processor cards (may process data stored on them) * * Most tools/applications already know what kind of card they want: * - homebanking tools want homebanking cards (HBCI card, a processor card) * - tools for German medical cards want a German medical card (which * is a memory card) * and so on. So it's only natural that the CTCardTrader allows you to * select a card by its type (memory/processor card). * * This class also allows to select the reader type to be used. * E.g. if you have two card readers: * - one with a keypad and display (like Kobil) * - one without both * then for homebanking cards, which require you to input a PIN should * only be accepted in the reader which has a keypad (for security reasons). * */ CTCardTrader *trader; /* ------------------------------------------------------------------------ * This actually creates the CTCardTrader. You may create as many as you * like. * The constructor of this class represents all the criteria described * above. Let's go through it one by one: */ trader= new CTCardTrader( /* If we are waiting for a card it sometimes happens * that there already IS a card inserted. * If this parameter is "false", then this already * inserted card may be used. * However, sometimes we want the user to remove the * currently inserted card (e.g. because we already * checked that card and now want to check the * next). * So if this parameter is "true" then a currently * inserted card will be ignored. * In most cases you want to use "false" */ false, /* These parameters allows to select the reader type * to be used by it's flags. * The first parameter of the following contains the * reader flags we are looking for, the second * contains a mask. * Let's say we want to choose a reader by the * property of having a keypad. * Then the reader flag mask (2nd parameter) should be * CHIPCARD_READERFLAGS_KEYPAD. * If we want a reader which actually DOES have a * keypad then we need to set the flags to * CHIPCARD_READERFLAGS_KEYPAD, too. * If we are only interested in a reader which does NOT * have a keypad then the corresponding bit MUST NOT be * set in the reader flags (1st parameter). * You may OR-combine multiple flags. */ 0, /* reader flags we want the reader to have */ 0, /* mask which defines what flags are interesting */ /* These parameters allow to select a card by the * status of the card reader. * The first determines the status we want, and the * second contains the mask which shows Libchipcard * which status bits do interest us (like with the * reader flags above). * In most cases we only want to have a CTCard object * for a reader which really has a card inserted. * To use the card, is must be free, no other program * must be working with it (Libchipcard makes sure * that only one client works with a card). * Summary: We want to wait until a card is inserted, * and which is not used by any other client. * That's what the nect two parameters represent. * You may OR-combine multiple status bits. * These flags are defined in "libchipcard.h". */ CHIPCARD_STATUS_INSERTED, /* status wanted */ CHIPCARD_STATUS_INSERTED | CHIPCARD_STATUS_LOCKED_BY_OTHER, /* status mask */ /** * The next parameter is a little bit difficult to * explain. * The chipcard daemon holds a list of clients, which * are waiting for a card. Whenever any bit of the * reader's status changes, the daemon goes through this * list. * But sometimes you are not interested in ALL possible * status changes. In most cases you are only interested * in the following change: A card has been inserted. * So this parameter now contains the bits of the * status whose change interest us. * In this case we only want to be informed when a card * has been inserted or removed. That is what this * parameter says. * However, in our example we don't want to be informed * when a card has been REMOVED, so the status wanted is * set to CHIPCARD_STATUS_INSERTED in the status * parameter above. * If you supply a 0 here (or set all bits to 1), then * all changes trigger a notification. */ CHIPCARD_STATUS_INSERTED ); /* ------------------------------------------------------------------------ * Until now the CTCardTrader didn't do anything. Most importantly it did * not connect to the chipcard daemon (=server). * When we call this method below the request is actually send to the * server, so the server learns in what cards and what readers we are * interested. As soon as there is a card available the server will send * a notification (see below). */ trader->start(); /* ------------------------------------------------------------------------ * Well, it's always nice to tell the user what to do ;-) */ fprintf(stderr,"Please insert your card.\n"); /* ------------------------------------------------------------------------ * Now this method actually checks whether a card is available. * We use a timeout of 30 seconds here. If there is no card available * within 30 seconds, the method will return an error. * However, to simplify this tutorial there is no error checking. */ trader->getNext(card, 30); /* ------------------------------------------------------------------------ * Let the user know that we found a card */ fprintf(stderr,"Card inserted, working.\n"); /* ------------------------------------------------------------------------ * To work with a card we need to open it. This will lock the card, so * that we are the only client which may use the card until we close it * again. */ card->openCard(); /* ------------------------------------------------------------------------ * We now simply check whether the card is a processor card or a memory * card and tell the user about the result, nothing wild ;-) */ if (card->isProcessorCard()) printf("The card is a processor card.\n"); else { printf("The card is a memory card (size=%d).\n", card->memorySize()); } /* ------------------------------------------------------------------------ * You should always close a card once you opened it. */ card->closeCard(); /* ------------------------------------------------------------------------ * This tells the chipcard daemon (=server) that we are not interested in * cards anymore. After this method has been successfully called we will * not get more notifications, even if an interesting card has been * inserted. */ trader->stop(); printf("Bye.\n"); return 0; }