/*************************************************************************** $RCSfile: libchipcard.h,v $ ------------------- cvs : $Id: libchipcard.h,v 1.19 2003/05/08 12:38:39 aquamaniac Exp $ begin : Sun Mar 10 2002 copyright : (C) 2002 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 libchipcard.h * * @short Contains the C API of LibChipCard. * @ingroup c_api */ #ifndef LIBCHIPCARD_H #define LIBCHIPCARD_H #include #ifdef __cplusplus extern "C" { #endif #define CHIPCARD_SUCCESS 0 #define CHIPCARD_ERROR_INVALID 1 #define CHIPCARD_ERROR_BUFFER 2 #define CHIPCARD_ERROR_CARD_REMOVED 3 #define CHIPCARD_ERROR_NO_REQUEST 4 #define CHIPCARD_ERROR_NO_MESSAGE 5 #define CHIPCARD_ERROR_BAD_CHANNEL_STATUS 6 #define CHIPCARD_ERROR_NO_COMMANDS 7 #define CHIPCARD_ERROR_NO_CONFIG 8 #define CHIPCARD_ERROR_UNREACHABLE 9 #define CHIPCARD_ERROR_DRIVER 10 #define CHIPCARD_ERROR_NO_READER 11 #define CHIPCARD_ERROR_COMMAND_NOT_FOUND 12 #define CHIPCARD_ERROR_BAD_RESPONSE 13 #define CHIPCARD_ERROR_NO_CARD 14 #define CHIPCARD_ERROR_ABORTED 15 #define CHIPCARD_ERROR_INTERRUPTED 16 #define CHIPCARD_ERROR_NO_TRANSPORT 17 #define CHIPCARD_ERROR_INTERNAL 99 #define CHIPCARD_STATUS_INSERTED CTREADERSTATUS_INSERTED #define CHIPCARD_STATUS_CONNECTED CTREADERSTATUS_CONNECTED #define CHIPCARD_STATUS_PROCESSOR CTREADERSTATUS_PROCESSOR #define CHIPCARD_STATUS_LOCKED_BY_OTHER CTREADERSTATUS_LOCKED_BY_OTHER #define CHIPCARD_READERFLAGS_KEYPAD CTREADERFLAGS_KEYPAD #define CHIPCARD_READERFLAGS_DISPLAY CTREADERFLAGS_DISPLAY CHIPCARD_API struct CHIPCARD_READERDESCRSTRUCT { unsigned int flags; char name[64]; char type[64]; }; CHIPCARD_API typedef struct CHIPCARD_READERDESCRSTRUCT CHIPCARD_READERDESCR; /** * @name Organisational Stuff * * Well, I don't know in which group to put these functions otherwise ;-) */ /*@{*/ /** * LibChipCard works asynchronously. Most functions only create a request * and enqueue it internally. Every time you call this function the enqueued * requests are actually send to the corresponding servers. So you will * never get an answer to a request if you don't call this function. * However, when using the C++ interface (@ref CTCard and derived classes) * then this function is called internally. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) */ CHIPCARD_API int ChipCard_Work(); /** * This function allows adding a card server to the internal list thus * bypassing the configuration files. This function is depracated and may * seize to exist in future versions, so please don't rely on it. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param addr address of the card server (either 3-dot notation or host name) * if port is "-1" then this must be the path to the unix domain socket * @param port port the server is listening on. If this is "-1" then unix * domain sockets will be used, in this case the address should be the path to * the socket file. */ CHIPCARD_API int ChipCard_AddServer(const char *addr, int port); /** * This function can be used to free a reader description received upon * @ref ChipCard_CheckConnect(). You should alway free such a reader * description by using this function. * @ingroup c_api * @author Martin Preuss */ CHIPCARD_API void ChipCard_ReaderDescr_free(CHIPCARD_READERDESCR *rd); /*@}*/ /** * @name Initialisation and Deinitialisation * * The functions in this group only need to be called hen you are using the * C interface only. The C++ classes automatically call them. */ /*@{*/ /** * This function initializes LibChipCard. It loads all necessary configuration * and command files. No communication with any server is done here. * This function can be called directly (and must be called if only C code * is to be used), but if you are using the C++ API (@ref CTCard and derived * classes) then this will be called internally when needed. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param configfile path and name of the client configuration file to use. If * this is NULL then the hardcoded default file will be used * @param section the name of the configuration section which is to be used. * If this is NULL (which is recommended) then the root of the configuration * file will be used. */ CHIPCARD_API int ChipCard_Init(const char *configfile, const char *section); /** * This functions shuts down LibChipCard (the client part). It should be * called when the program exits. However, when using the C++ API then * it will be called internally when needed. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) */ CHIPCARD_API void ChipCard_Fini(); /*@}*/ /** * @name Configuration File Based APDU Engine * * The functions of this group are allow looking up APDU commands. * This engine allows adjusting LibChipCard to special cards and readers * without recompiling LibChipCard. */ /*@{*/ /** * This functions tries to lookup a card command (APDU) based on the * type of the reader and the card. This allows adjusting commands to * special cards or readers without the need for recompilation of * LibChipCard. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param command name of the command (like "select_mf") * @param readertype type of the reader (either "towitoko", "kobil", * "cyberjack" or "other") * @param buffer buffer to store the complete path and name of the command * found * @param bufferlen size of the buffer provided */ CHIPCARD_API int ChipCard_LocateCommand(const char *command, const char *readertype, const char *cardtype, char *buffer, int bufferlen); /** * Checks whether a given command exists. You can provide a full path here * (including readertype and card type separated by "/") * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param command full path of the command to check for */ CHIPCARD_API int ChipCard_ExistsCommand(const char *command); /** * Creates an APDU (card command) from the given parameters. * This uses the core of the new configuration file driven command * engine. * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) */ int ChipCard_MakeAPDU(char *buffer, int *bufferlen, const char *command, int argc, ...); /*@}*/ /** * @name General Request and Response Handling * * This group contains functions which can be applied to any pending request. */ /*@{*/ /** * Each request can be identified by its request id. This function here * checks whether there is a response to the given request pending. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid unique request id of the request to check for responses */ CHIPCARD_API int ChipCard_CheckResponse(int requestid); /** * If you issued a request and for any reason want to withdraw it (thereby * telling LibChipCard that you're no longer interested in a response) then * you are expected to call this function. It frees all ressources occupied * by the request. All future responses to this request which may arrive * after withdrawing the request are ignored. * @ingroup c_api * @author Martin Preuss * @param request id unique request id */ CHIPCARD_API void ChipCard_WithdrawRequest(int requestid); /** * This only marks the request as abandoned. When the response for this * request arrives, it will be discarded and the request itself will * be deleted. However, if there already is a response to this request * this request will immediately be deleted. * @ingroup c_api * @author Martin Preuss * @param request id unique request id */ CHIPCARD_API void ChipCard_AbandonRequest(int requestid); /*@}*/ /** * @name Requests * * LibChipCard works asynchronously. Nearly all actions you want LibChipCard * to take are in form of a request. Generally you call a request function * (ChipCard_RequestXYZ()), then @ref ChipCard_Work() (repeatedly until a * response arrives) and the appropriate check function (ChipCard_CheckXYZ()). * The check function is the one that returns the results of a request (if * it successfully returns) */ /*@{*/ /** * This function requests the allocation of a card reader. A card reader must * be allocated in order to use it. After you have finished using the reader * you should release it by @ref ChipCard_RequestReleaseReader(). * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid pointer to an integer variable to receive the request id * This is only altered if this function returns without an error * @param tid the id of the terminal. You can get this by using * @ref ChipCard_RequestFindReader() or @ref ChipCard_RequestWaitReader(). */ CHIPCARD_API int ChipCard_RequestAllocReader(int *requestid, unsigned int tid); /** * This function checks whether there is a response for the request. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid unique request id assigned by the matching request * function * @param thdl pointer to an integer variable to receive the terminal handle * This one is not to be confused with the tid param given to * @ref ChipCard_RequestAllocReader() * @param rd pointer to a pointer to receive the description of the allocated * reader. You are expected to call @ref ChipCard_ReaderDescr_free() when * you don't need this description anymore (you take over ownership for this * item) */ CHIPCARD_API int ChipCard_CheckAllocReader(int requestid, int *thdl, CHIPCARD_READERDESCR **rd); /** *This function requests to release a reader. You are expected to call this * function when you are finished using the reader in order to free * ressources allocated locally by the reader. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid pointer to an integer variable to receive the request id * This is only altered if this function returns without an error */ CHIPCARD_API int ChipCard_RequestReleaseReader(int *requestid, unsigned int tid); /** * This function checks whether there is a response for the request. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid unique request id assigned by the matching request * function */ CHIPCARD_API int ChipCard_CheckReleaseReader(int requestid); /** * This function requests connecting a card to the given reader. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid pointer to an integer variable to receive the request id * This is only altered if this function returns without an error * @param thdl terminal handle assigned by @ref ChipCard_RequestAllocReader() */ CHIPCARD_API int ChipCard_RequestConnect(int *requestid, unsigned int thdl, int cardId, int waitForIt); /** * This function requests aborting a pending connection request * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid pointer to an integer variable to receive the request id * This is only altered if this function returns without an error * @param thdl terminal handle assigned by @ref ChipCard_RequestAllocReader() */ CHIPCARD_API int ChipCard_RequestStopConnect(int *requestid, unsigned int thdl, int prevRequest); CHIPCARD_API int ChipCard_CheckStopConnect(int requestid, int *result); /** * This function checks whether there is a response for the request. * All return parameters are only modified upon successfull return. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid unique request id assigned by the matching request * function * @param result pointer to an integer variable to receive the result of the * connect request. Please note that the return value of this function can * be "OK" even if the connect itself did not succeed. This is because * the return value of this function only tells you whether the request has * been answered. You need this parameter here to check for the result of the * connect itself. * @param atrbuffer pointer to a buffer which is filled upon successful return * with the ATR ("Answer To Reset") string returned by a chipcard upon * connect. This ATR is normally used to identify/verify the card type since * it is quite unique. * @param atrbufferlength pointer to variable that tells this function about * the size of the buffer supplied. Upon return that variable contains the * number of bytes actually used by the ATR string. It is guaranteed to * never exceed the entry value. Please note that the ATR string is a binary * string not terminated by a zero byte (unlike ASCIIZ strings). */ CHIPCARD_API int ChipCard_CheckConnect(int requestid, int *result, char *atrbuffer, int *atrbufferlength); /** * This function requests disconnecting a card in the given reader. * The card is reset by this function, so that any security status is * guaranteed to be cleared upon successfull disconnect. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid pointer to an integer variable to receive the request id * This is only altered if this function returns without an error * @param thdl terminal handle assigned by @ref ChipCard_RequestAllocReader() */ CHIPCARD_API int ChipCard_RequestDisconnect(int *requestid, unsigned int thdl); /** * This function checks whether there is a response for the request. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid unique request id assigned by the matching request * function * @param result pointer to an integer variable to receive the result of the * disconnect request. Please note that the return value of this function can * be "OK" even if the disconnect itself did not succeed. This is because * the return value of this function only tells you whether the request has * been answered. You need this parameter here to check for the result of the * disconnect itself. */ CHIPCARD_API int ChipCard_CheckDisconnect(int requestid, int *result); /** * This function requests executing a raw APDU on the card in the given * reader. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid pointer to an integer variable to receive the request id * This is only altered if this function returns without an error * @param thdl terminal handle assigned by @ref ChipCard_RequestAllocReader() * @param sendBuffer pointer to the buffer containing the APDU to be executed * @param sendBufferLength length of the send buffer */ CHIPCARD_API int ChipCard_RequestCommand(int *requestid, unsigned int thdl, const char *sendBuffer, int sendBufferLength); /** * This function checks for the result of @ref ChipCard_RequestCommand() and * @ref ChipCard_RequestCommand2(). * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid unique request id assigned by the matching request * function * @param result pointer to an integer variable to receive the result of the * command request. Please note that the return value of this function can * be "OK" even if the command itself did not succeed. This is because * the return value of this function only tells you whether the request has * been answered. You need this parameter here to check for the result of the * command itself. * @param recvBuffer pointer to a buffer for the answer from the card. It * must at least have space for two bytes (the two result codes of any APDU) * @param recvBufferLength pointer to an integer variable initially * containing the length of the buffer provided. Upon return this holds the * number of bytes actually stored in the buffer. This is guaranteed to never * exceed the initial value. */ CHIPCARD_API int ChipCard_CheckCommand(int requestid, int *result, char *recvBuffer, int *recvBufferLength); /** * This function requests to find a reader by drivertype, readertype and/or * readerflags. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid pointer to an integer variable to receive the request id * This is only altered if this function returns without an error * @param readerType (e.g. "towitoko","kobil", "cyberjack") * or -1 to match all) * @param readerFlags (any ORed combination of CHIPCARD_READERFLAGS_KEYPAD and * CHIPCARD_READERFLAGS_DISPLAY) * @param readerFlagsMask may hold the same values as the readerFlags, but * this one here is interpreted as a mask. E.g. if this is zero then all * readerflags match. */ CHIPCARD_API int ChipCard_RequestFindReader(int *requestid, const char *readerType, unsigned int readerFlags, unsigned int readerFlagsMask); /** * This function checks whether there is a response for the request. * Since a FindReader request is send to all registered servers you should * call this function repeatedly (intermixed with @ref ChipCard_Work())until * CHIPCARD_ERROR_NO_REQUEST is returned. If you have found a reader * before CHIPCARD_ERROR_NO_REQUEST is returned then you should withdraw the * request by calling @ref ChipCard_WithdrawRequest(). * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid unique request id assigned by the matching request * function * @param readerbuffer a pointer to an integer array to receive the ids * of the terminals found. Each of the entries returned in this buffer can * be fed to @ref ChipCard_RequestAllocReader. * @param readerBufferLength size of the buffer (as the number of integer * values the array contains, not the size in bytes!) */ CHIPCARD_API int ChipCard_CheckFindReader(int requestid, unsigned int *readerbuffer, int *readerBufferLength); /** * This function requests the status of a card reader. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid pointer to an integer variable to receive the request id * This is only altered if this function returns without an error * @param thdl terminal handle assigned by @ref ChipCard_RequestAllocReader() */ CHIPCARD_API int ChipCard_RequestStatReader(int *requestid, int thdl); /** * This function checks whether there is a response for the request. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid unique request id assigned by the matching request * function * @param result pointer to an integer variable to receive the result of the * stat request. Please note that the return value of this function can * be "OK" even if the stat itself did not succeed. This is because * the return value of this function only tells you whether the request has * been answered. You need this parameter here to check for the result of the * stat itself. * @param status pointer to a variable to receive the status of the reader * upon successfull return. It holds any OR combination of CHIPCARD_STATUS_XYZ * values. * @param atrbuffer pointer to a buffer which is filled upon successful return * with the ATR ("Answer To Reset") string returned by a chipcard upon * connect. This ATR is normally used to identify/verify the card type since * it is quite unique. * @param atrlen pointer to variable that tells this function about * the size of the buffer supplied. Upon return that variable contains the * number of bytes actually used by the ATR string. It is guaranteed to * never exceed the entry value. Please note that the ATR string is a binary * string not terminated by a zero byte (unlike ASCIIZ strings). */ CHIPCARD_API int ChipCard_CheckStatReader(int requestid, int *result, unsigned int *status, char *atrbuffer, int *atrlen); /** * This is nearly the same as the function above, but it allows to * additionally give a delta status. * Only changes in those parts of the reader status, whose bits are set * in statusDelta are checked. So you can now effectively ignore some * status changes. * E.g. if statusDelta is "0" then all status changes are ignored, * so you will never receive a status change notification. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) */ CHIPCARD_API int ChipCard_RequestWaitReader(int *requestid, int mustChange, const char *readerType, unsigned int readerFlags, unsigned int readerFlagsMask, unsigned int status, unsigned int statusMask, unsigned int statusDelta); /** * This function checks whether there is a response for the request. * @ingroup c_api * @author Martin Preuss * @return result code (0==ok, all other values are CHIPCARD_ERROR_XYZ values) * @param requestid unique request id assigned by the matching request * function * @param tid pointer to a variable to receive the id of a matching terminal. * This is only altered if the function successfully returns. * @param status pointer to a variable to receive the current status of the * terminal identified by tid * @param readerflags pointer to a variable to receive the readerflags of the * terminal identified by tid */ CHIPCARD_API int ChipCard_CheckWaitReader(int requestid, int *tid, unsigned int *status, unsigned int *readerflags, unsigned int *cardId); /** * This function stops waiting for further reader notifications induced by * @ref ChipCard_RequestWaitReader(). It releases all ressources allocated * by this request. * @ingroup c_api * @author Martin Preuss * @param prevRequest unique request id assigned by the matching request * function */ CHIPCARD_API int ChipCard_StopWaitReader(int prevRequest); /*@}*/ /** * @internal */ CHIPCARD_API int ChipCard_RequestPing(int *requestid, int serviceid); /** * @internal */ CHIPCARD_API int ChipCard_CheckPing(int requestid); #ifdef __cplusplus } #endif #endif