Professional Documents
Culture Documents
1.1 Introduction
This document is a comprehensive documentation of the RCL/BFL (RF Component Library / Basic
Function Library) architecture, parts and usage. It includes a description of the component design,
the different components including their internal parts and how to connect the different components
to use them in a functional framework. Example code demonstrates the usage of the library. No
detailed description of the source code is contained, however the source code itself is available.
First, the library must fully support all features on small systems (microcontrollers) with low
resources, and
second, the library shall add convenience for larger systems.
As a consequence, those who build small microcontroller-based software, will rely on the C-part of the
BFL, while others, writing e.g. handheld or even PC programs will tend to use the C++ wrapper.
Important note: The macro RCL CPP must be globally (e.g compiler settings) defined in order
to be able to use the C++ library extensions.
Note: The components with the dotted line in the figure above mark components that are currently
not implemented.
No warranties of any kind are given with respect to the information provided herein except that Philips Semiconduc-
tors, Business Unit Identification warrants it has the right to make the disclosure. No patent, copyright, trademark
or other proprietary right or license is granted by this publication. No warranties of any kind are made as to the
particular application of the data and information contained in these materials and Philips Semiconductors, Business
Unit Identification hereby disclaims liability for any consequences relation to the use of this information.
Philips Semiconductors, Business Unit Identification does not assume any liability arising out of the applications and
application software wihich is included in the Evaluation Package or use of any product or circuit described herein.
This layer is optional. Its purpose is to abstract the bus specific details. In most cases the BAL is
omitted and the Register Control Unit is the lowest level. In some cases however the BAL can help
to increase portability (e.g. to hide the different system calls between LINUX and Windows).
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Data Structures
struct C JOINER RS 232 PC BAL PARAMS
struct BAL WRITEBUS PARAM
struct C BAL
Typedefs
typedef BAL WRITEBUS PARAM BAL READBUS PARAM
typedef RCLSTATUS( C BAL WRITEBUS )(BAL WRITEBUS PARAM )
typedef RCLSTATUS( C BAL READBUS )(BAL READBUS PARAM )
Functions
void JoinerBalRs232PcInitialise (C BAL cif, void communication parameters)
RCLSTATUS JoinerBalRs232PcWriteBus (BAL WRITEBUS PARAM writebus param)
RCLSTATUS JoinerBalRs232PcReadBus (BAL WRITEBUS PARAM readbus param)
void JoinerBalRs232LinuxInitialise (C BAL cif, void communication parameters)
RCLSTATUS JoinerBalRs232LinuxWriteBus (BAL WRITEBUS PARAM writebus param)
RCLSTATUS JoinerBalRs232LinuxReadBus (BAL WRITEBUS PARAM readbus param)
2.1 Peripheral Device Bus Abstraction Layer Component 5
Parameters:
cif [in/out] C object interface structure, see rclstruct.h
communication parameters [in/out] Pointer to the communication parameter structure.
This function should be called first to initialise the BAL-Layer and set required parameters. An own
function pointer is typedefed for this function to enable the call within a generic C++ BAL wrapper.
See INCBAL.H .
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Parameters:
writebus param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INVALID DEVICE STATE
RCLSTATUS INTERFACE ERROR
RCLSTATUS INSUFFICIENT RESOURCES
This function writes the data byte directly to the used bus. All interface specific actions for writing
are done here also.
Parameters:
readbus param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INVALID DEVICE STATE
RCLSTATUS INTERFACE ERROR
RCLSTATUS INSUFFICIENT RESOURCES
This function reads one byte directly from the used bus. All interface specific actions for reading are
done here also.
Parameters:
cif [in/out] C object interface structure, see rclstruct.h
communication parameters [in/out] Pointer to the communication parameter structure.
An own function pointer is typedefed for this function to enable the call within a generic C++ BAL
wrapper. See INCBAL.H .
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Parameters:
writebus param [in/out] Struct with communication parameters - its members: See
RCLSTRUCT.H .
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INTERFACE ERROR
Parameters:
readbus param [in/out] Struct with communication parameters - its members: See
RCLSTRUCT.H .
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INTERFACE ERROR
This component is responsible for reading and writing from and to the registers of the RC522. Its
lower layer is the Bal and the upper layers are RcOpCtl, RcIo and Iso14443 3.
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Data Structures
struct RCREGCTL SETREG PARAM
struct RCREGCTL MODIFY PARAM
struct C RC REG CTL
struct C JOINER RS 232 PC RC REG CTL PARAMS
Typedefs
typedef RCREGCTL SETREG PARAM RCREGCTL GETREG PARAM
typedef RCLSTATUS( C RC REG CTL SETREG )(RCREGCTL SETREG PARAM )
typedef RCLSTATUS( C RC REG CTL GETREG )(RCREGCTL GETREG PARAM )
Functions
void JoinerRcRegCtlRs232PcInitialise (C RC REG CTL cif, void p params, C BAL p -
lower)
RCLSTATUS JoinerRcRegCtlRs232PcSetRegister (RCREGCTL SETREG PARAM setreg -
param)
RCLSTATUS JoinerRcRegCtlRs232PcGetRegister (RCREGCTL GETREG PARAM getreg -
param)
RCLSTATUS JoinerRcRegCtlRs232PcModifyRegister (RCREGCTL MODIFY PARAM
modify param)
Parameters:
cif [in] Pointer to the instance of the C object interface structure, see rclstruct.h
p params [in] Pointer to the internal operation variables structure instance.
p lower [in] Pointer to the underlying layer.
This function shall be called first to initialise the register control component. An own function
pointer is typedefed for this function to enable the call within a generic C++ RC-Reg-Ctl wrapper.
See INCRCREGCTL.H .
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Parameters:
setreg param [in] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INTERFACE ERROR
Parameters:
getreg param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
Parameters:
modify param [in] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INTERFACE ERROR
The blocks listed here contain hardware dependent code since they access registers.
The I/O components thus rely on the component supporting register manipulation, namely the RC
Register Control. The various components are listed below. Except of the auxilary functionality
all components have an object interface to the upper layers. The auxilary function combines some
often used transmit and receive functionality and error checking and is directly called by the other
components using their pointer to the lower layer.
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Modules
Operation Control Component
RC-I/O Functionality (Receive/Transmit)
ISO 14443-3 Type A
Auxilary Functionality
This component abstacts access to the registers or RF chip configuration respectively by combining
multiple register accesses, or changing only certain bits of a register.
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Data Structures
struct RCOPCTL ATTRIB PARAM
struct C RC OP CTL
struct C JOINER RC OP CTL PARAMETERS
Typedefs
Functions
void JoinerRcOpCtlInitialise (C RC OP CTL cif, void km, C RC REG CTL p lower)
void JoinerRcOpCtlSetWaitEventCb (RCL SET WAIT EVENT CB PARAM set wec param)
RCLSTATUS JoinerRcOpCtlSetAttribute (RCOPCTL ATTRIB PARAM attrib param)
RCLSTATUS JoinerRcOpCtlGetAttribute (RCOPCTL ATTRIB PARAM attrib param)
Parameters:
cif [in] Pointer to an instance of the C object interface structure, see rclstruct.h
km [in] Pointer to the internal control variables structure instance.
p lower [in] Pointer to the underlying functionality.
This function shall be called first to initialise the operation control component. There the C-Layer, the
internal variables and the underlaying layer are initialised. An own function pointer is typedefed for
this function to enable the call within a generic C++ RC-OperationControl wrapper. See INCRCIO.H
.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Parameters:
attrib param [in] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INTERFACE ERROR
This function does various hardware dependent settings, e.g. store IDs, set RxGain.
Parameters:
attrib param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INTERFACE ERROR
This function reads out various hardware dependent settings, e.g. read IDs, get actual RxGain value.
This component handles the I/O functionality. Therefore the functions Transmit, Receive, Transceive
and the special function MfAuthent are implemented. All functions use the function RcAux for
common processing functions. Some functionality is mode-depending supporting easier handling of
the peripheral.
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Data Structures
struct RCIO TRANSCEIVE PARAM
struct RCIO TRANSMIT PARAM
struct RCIO RECEIVE PARAM
struct C RC IO
struct C JOINER RC IO PARAMETERS
Typedefs
typedef RCIO TRANSMIT PARAM RCIO MFAUTHENT PARAM
typedef RCLSTATUS( C RCIO TRANSCEIVE )(RCIO TRANSCEIVE PARAM )
typedef RCLSTATUS( C RCIO TRANSMIT )(RCIO TRANSMIT PARAM )
typedef RCLSTATUS( C RCIO RECEIVE )(RCIO RECEIVE PARAM )
typedef RCLSTATUS( C RCIO MFAUTHENT )(RCIO MFAUTHENT PARAM )
Functions
void JoinerRcIoInitialise (C RC IO cif, void rp, C RC REG CTL p lower, unsigned char
initiator not target)
void JoinerRcIoSetWaitEventCb (RCL SET WAIT EVENT CB PARAM set wec param)
RCLSTATUS JoinerRcIoTransceive (RCIO TRANSCEIVE PARAM transceive param)
RCLSTATUS JoinerRcIoTransmit (RCIO TRANSMIT PARAM transmit param)
RCLSTATUS JoinerRcIoReceive (RCIO RECEIVE PARAM receive param)
RCLSTATUS JoinerRcIoMfAuthent (RCIO MFAUTHENT PARAM mfauthent param)
Parameter structure for MF-Authent helper is equal to Transmit parameter. Since the Mifare (R)
function for Authentication is part of the RF chips I/O capabilities, it must be handled here. The
function takes the authentication parameters in the tx buffer member. Composition of the data is
done in the Mifare component.
Definition at line 413 of file rclstruct.h.
Parameters:
cif [in] C object interface structure, see rclstruct.h.
rp [in] Pointer to the internal control variables structure.
p lower [in] Pointer to the underlying layer, in this case register control.
initiator not target [in] Specifier for mode whether to support Initiator or Target.
This function shall be called first to initialise the IO component. There the C-Layer, the internal
variables, the underlaying layer and the device mode are initialised. An own function pointer is
typedefed for this function to enable the call within a generic C++ RC-I/O wrapper. See file
INCRCIO.H .
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Parameters:
transceive param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INVALID DEVICE STATE
This function directly uses the auxiliary function JoinerRcAuxSingleCommand for initiator mode.
For target mode this function is disabled and replaced by JoinerRcIoTransmit and JoinerRcIoReceive
which also use the transceive command for bit syncronicity.
The rx buffer size parameter sets the maximum receive data length in bytes. Even if more data is
received, no buffer overflow may occure.
In combination with a transparent register read and write command set, this function enables a
completely transparent communication between two devices.
Note:
TX and RX buffers may overlap or even be the same.
In case of an error, the appropriate error code is set. Nevertheless all received data during the
RF-Communication is returned. This is done for debugging reasons.
Neither framing and speed nor timeout and CRC are modified by this function. These parameters
should be set in advance.
Parameters:
transmit param [in] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INVALID DEVICE STATE
This function is devided into two parts. One for the initiator mode and one for the reader mode.
In initiator mode the function JoinerRcAuxSingleCommand is called and the transmit command of
RC522 is executed. No response is expected.
In target mode there is first a check if the transceive command is active, because sending without any
previous reception is forbidden. Then the function JoinerRcAuxSingleCommand is called using the
transceive command of RC522.
Note:
Neither framing and speed nor timeout and CRC are modified by this function. These parameters
should be set in advance.
Parameters:
receive param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
This function is devided into two parts. One for the initiator mode and one for the reader mode.
In initiator mode the function JoinerRcAuxSingleCommand is called and the receive command of
RC522 is executed.
In target mode the function JoinerRcAuxSingleCommand is called and the transceive command of
RC522 is executed.
In both modes the rx buffer size parameter sets the maximum receive data length in bytes. Even if
more data is received, no buffer overflow may occure.
Note:
In case of an error, the appropriate error code is set. Nevertheless all received data during the
RF-Communication is returned. This is done for debugging reasons.
Neither framing and speed nor timeout and CRC are modified by this function. These parameters
should be set in advance.
Parameters:
mfauthent param [in] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INVALID DEVICE STATE
This function is directly called from Mifare Authentication function where the data is prepared and
handled over using the tx buffer. The function calls JoinerRcAuxSingleCommand where the Authen-
tication command of RC522 is performed.
Note:
Neither framing and speed nor timeout and CRC are modified by this function. These parameters
should be set in advance.
This component contains the activation and deactivation commands according to the ISO 14443 Part
3 Type A which are functions for Request, Anticollission/Select and HaltA.
These are used to start communication to either a MIFARE card, a card supporting ISO14443 Part
4.
An overview about the commands and what commands must be followed by which one will be done
in the table below.
Command Abbr. Code Argument Response Possible after
Request ALL REQ 52 None Tag Type cards POR, HALT,
(ATQA) communication failure
Request IDLE REQ 26 None Tag Type cards POR,
(ATQA) communication failure
Anticollision AC 93, 95, 97 (optional parts of the (rest of) cds REQ, AC
cards serial number) serial number
Select SEL 93, 95, 97 Card serial number Answer To REQ, AC
Select communication failure
Halt HALT 50 Dummy address None AC, SEL,
any MIFARE command
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Data Structures
struct ISO14443 3 REQUEST A PARAM
struct ISO14443 3 ANTICOLLISIONSELECT PARAM
struct ISO14443 3 HALT A PARAM
struct C ISO 14443 3A
struct C JOINER ISO 14443 3 PARAMETERS
Typedefs
typedef ISO14443 3 ANTICOLLISIONSELECT PARAM ISO14443 3 SELECT PARAM
typedef RCLSTATUS( REQUESTA )(ISO14443 3 REQUEST A PARAM )
typedef RCLSTATUS( ANTICOLLISIONSELECT )(ISO14443 3 -
ANTICOLLISIONSELECT PARAM )
typedef RCLSTATUS( SELECT )(ISO14443 3 SELECT PARAM )
typedef RCLSTATUS( HALTA )(ISO14443 3 HALT A PARAM )
Functions
void JoinerIso14443 3Initialise (C ISO 14443 3A cif, void rp, C RC REG CTL p lower, un-
signed char initiator not target)
void JoinerIso14443 3SetWaitEventCb (RCL SET WAIT EVENT CB PARAM set wec -
param)
Parameters:
cif [in/out] C object interface structure, see rclstruct.h
rp [in/out] Pointer to the internal control variables structure.
p lower [in] Pointer to the underlying layers function.
initiator not target [in] Specifier for mode whether to support Initiator or Target.
This function shall be called first to initialise the ISO14443-3 component. There the C-Layer, the
internal variables, the underlaying layer and the device mode are initialised. An own function pointer
is typedefed for this function to enable the call within a generic C++ ISO14443 3 wrapper. See
INCRCIO.H.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Parameters:
request a param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS COLLISION ERROR
RCLSTATUS PROTOCOL ERROR
RCLSTATUS INVALID DEVICE STATE
This command handles the Request procedure of ISO14443-3. Depending on the Request Code and
the state of the cards in the field all cards reply with their Tag-Type synchronously. The time between
end of the Request command and start of reply of the card is exactly 8 9.44 us long. The Tag-Type
field is 16 bits long and only one bit out of 16 is set.
When cards with different Tag-Types are in field, the MF RC500 is able to identify all types of cards
in the RF-field. Further more, the Tag-Type is used to identify a card with cascaded serial number.
Double and Triple serial numbers are possible.
Note:
In case of an error, the appropriate error code is set. Nevertheless all received data during the
RF-Communication is returned for debugging reasons.
Future cards will work also with other request codes.
Parameters:
anticollisionselect param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INVALID PARAMETER
RCLSTATUS BITCOUNT ERROR
RCLSTATUS WRONG UID CHECKBYTE
RCLSTATUS INVALID DEVICE STATE
This command combines the ISO14443-3 functions of anticollision and select. The functionality is
split up into two independent internal procedures. One to do the anticollision, the other one to do the
select. The cascade level is automatically increased if the Cascade Tag for a further level is received.
The checkbyte is verified, but not stored in the buffer.
The sel lv1 code contains the select code of cascade level 1. This is 0x93 for ISO14443-3 compatible
devices.
The uid references a buffer which may contain the known part of the uid when the function is called.
When the function returns to the calling procedure, this buffer contains the received serial number
of the target device. The length is according to the cascade level of the ID. The indicator of another
cascade level (0x88) is not removed and also stored in the buffer.
The uid length parameter is the bit count (!) of the ID. As input it is the number of known bits, as
output it shows the ID length, in bits, which is always a multiple of 32.
At the end this function selects a card by the specified serial number. All other cards in the field fall
back into the idle mode and they are not longer involved during the further communication.
Note:
In case of an error, the appropriate error code is set. Nevertheless all received data during the
RF-Communication is returned for debugging reasons.
Parameters:
select param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS INVALID PARAMETER
RCLSTATUS BITCOUNT ERROR
RCLSTATUS INVALID DEVICE STATE
This command only performs the select of a known device. For detailed information on the parameters
see the decription of JoinerIso14443 3AnticollisionSelect command.
The sel lv1 code is the first command to be sent to the passive device.
The uid contains the ID of the device. All 3 cascade levels can be transferred at once to the function.
The uid length parameter defines whether the ID is single, double or triple.
At the end this function selects a card by the specified serial number. All other cards in the field fall
back into the idle mode and they are not longer involved during the further communication.
Note:
In case of an error, the appropriate error code is set. Nevertheless all received data during the
RF-Communication is returned. This is done for debugging reasons.
Parameters:
halt a param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
This block conains the helper functions for the IO, the operation control and the ISO14443 Part 3
component. It is directly called by these functions (not via the RCL/BFL interface logic). The pointer
to the lower layer is directly handed over via one member in the parameter data structure. One helper
function is called JoinerRcAuxSingleCommand and handles transmission, reception and error checking
of the received data. A so called waterlevel is defined here but not used in the implementation for
the serial interface. Therefore this function is able to handle only up to 64 bytes of data.
The struct RCAUX SINGLE COMMAND PARAM contains the pointer to the lower component, the
command to operate, the pointer to the transmit buffer, the transmit buffer size, the pointer to the
receive buffer, the information about the received bytes and the received bits.
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Functions
RCLSTATUS JoinerRcAuxSingleCommand (RCAUX SINGLE COMMAND PARAM single -
command param)
Parameters:
single command param [in/out] Pointer to the parameter structure, see rclstruct.h
Returns:
RCLSTATUS SUCCESS
RCLSTATUS ACK SUPPOSED
RCLSTATUS BUFFER OVERFLOW
RCLSTATUS COLLISION ERROR
RCLSTATUS CRC ERROR
RCLSTATUS JOINER TEMP ERROR
RCLSTATUS UNSUPPORTED COMMAND
RCLSTATUS PARITY ERROR
RCLSTATUS PROTOCOL ERROR
RCLSTATUS RF ERROR
RCLSTATUS ERROR NY IMPLEMENTED
This module handles the common part of the send and receive functionality. It also does the filling
of the FIFO of the RC522 and all the error checking for the response data. It is mainly used by all
components of the hardware dependent layer of the BFL.
For this module there is only the C-Interface existing. It shall be called directly.
Note:
TX and RX buffers may overlap or even be the same.
In case of an error, the appropriate error code is set. Nevertheless all received data during the
RF-Communication is returned. This is done for debugging reasons.
Neither framing and speed nor timeout and CRC are modified by this function. These parameters
should be set in advance.
ISO/IEC 14443-4 (T=CL) Protocol Activation for Type A and ISO/IEC 14443-4 (T=CL)
Protocol Functionality and
ID Manger.
The lower layer of the functions is the RC-IO component. The upper layer is an application, a
surrounding library (e.g. shared lib) some middleware or any embedding software.
Modules
MIFARE Reader Command Set
ISO/IEC 14443-4 (T=CL) Protocol Activation for Type A
ISO/IEC 14443-4 (T=CL) Protocol Functionality
ID Manger
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Data Structures
struct MIFARE CMD PARAM
struct C MIFARE READER
struct C MF RD INTL PARAMS
Commands
Command definitions for Mifare operation. These command bytes comply to the MIFARE specifica-
tion and serve as one parameter for the MIFARE transaction commands defined within the scope of
this implementation.
Size Definitions
These definitions are important for the caller (user). The sizes are also internally checked and used
for request/response processing.
Typedefs
typedef RCLSTATUS( MIFARE GENERIC SINGLE )(MIFARE CMD PARAM )
typedef RCLSTATUS( MIFARE GENERIC DOUBLE )(MIFARE CMD PARAM )
typedef RCLSTATUS( MIFARE CMD )(MIFARE CMD PARAM )
Functions
void MifareReaderInitialise (C MIFARE READER cif, void mp, C RC IO p lower, unsigned
char p trxbuffer)
RCLSTATUS MifareReaderTransaction (MIFARE CMD PARAM cmd param)
Parameters:
cif [in] Pointer to an instance of the C object interface structure, see rclstruct.h
mp [in] Pointer to the alredy allocated internal control variables structure.
p lower [in] Pointer to the underlying layer RC-I/O.
p trxbuffer [in] Pointer to the system-wide TRx buffer, allocated and managed by the embed-
ding software. The buffer serves as the source/destination buffer for the underlying RC-I/O
Transceive functionality.
Examples:
MifareReaderC.c.
Parameters:
cmd param (
[in/out] Struct with communication parameters - its members: See RCLSTRUCT.H .
Returns:
RCLSTATUS SUCCESS
RCLSTATUS COLLISION ERROR
RCLSTATUS PROTOCOL ERROR
RCLSTATUS INVALID DEVICE STATE
Other RCLSTATUS values depending on the underlying RC-I/O features.
The main MIFARE reader protocol entry point. All MIFARE functionality is concentrated in this
place.
The ISO 14443-4 (T=CL) protocol handles APDU-based data exchange with contactless cards
(PICCs). All protocol-related actions such as frame-composition/analysis, chaining of information,
error-handling and the like are done internally.
This component is designed to be independent from the RF chip hardware and the I/O subsystem.
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Data Structures
struct ISO14443 4 RATS PARAM
struct ISO14443 4 PPS PARAM
struct C ISO14443 4A ACTIVATION
Typedefs
Functions
RCLSTATUS Iso14443 4A Activation Initialise (C ISO14443 4A ACTIVATION cif,
ISO14443 4 PROTOCOL PARAM p td, unsigned char p trxbuffer, unsigned short trxbuffer-
size, C RC IO p lower)
RCLSTATUS Iso14443 4A Rats (ISO14443 4 RATS PARAM rats param)
RCLSTATUS Iso14443 4A Pps (ISO14443 4 PPS PARAM pps param)
Parameters:
cif [in] C object interface structure, see rclstruct.h .
p td [in] Pointer to the Communication Parameters structure. This structure is filled by RATS
and PPS and to be handed over to the exchange protocol (ISO14443 4) object.
p trxbuffer [in] Pointers to TX and RX buffer, used by the protocol for intermediate storage.
trxbuffersize [in] Size of TX and RX buffer, used by the protocol for intermediate storage.
p lower [in] Pointer to the underlying layers TRx function.
Set up the ISO 14443-4 protocol entry. After this function the Component is operational.
Examples:
Iso14443 4 ReaderC.c.
Parameters:
rats param [in/out] Parameter structure, see rclstruct.h;
Returns:
RCLSTATUS code.
Parameters:
pps param [in/out] Parameter structure, see rclstruct.h .
Returns:
RCLSTATUS code.
The ISO 14443-4 (T=CL) protocol handles APDU-based data exchange with contactless cards
(PICCs). All protocol-related actions such as frame-composition/analysis, chaining of information,
error-handling and the like are done internally.
This component is designed to be independent from the RF chip hardware and the I/O subsystem.
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Data Structures
struct ISO14443 4 PROTOCOL PARAM
struct ISO14443 4 EXCHANGE PARAM
struct ISO14443 4 DESELECT PARAM
struct ISO14443 4 CB SET WTX PARAM
struct ISO14443 4 CB SET READER PARAM
struct ISO14443 4 SET CB PARAM
struct C ISO14443 4
struct ISO14443 4 COMMUNICATION PARAMETERS
Member Typedefs
Protocol Typedefs
Callback Typedefs
Defines
#define ISO14443 4 CONTINUE CHAINING (0x01)
Typedefs
typedef ISO14443 4 DESELECT PARAM ISO14443 4 PRESENCE CHECK PARAM
Functions
RCLSTATUS Iso14443 4Initialise (C ISO14443 4 cif, ISO14443 4 COMMUNICATION -
PARAMETERS p td, C RC IO p lower)
void Iso14443 4SetCallbacks (ISO14443 4 SET CB PARAM set cb param)
void Iso14443 4SetProtocolParameters (void cif, void p protocol param, unsigned char max -
retry)
void Iso14443 4ResetProtocol (void cif)
RCLSTATUS Iso14443 4Exchange (ISO14443 4 EXCHANGE PARAM exchange param)
RCLSTATUS Iso14443 4PresenceCheck (ISO14443 4 PRESENCE CHECK PARAM
presence check param)
RCLSTATUS Iso14443 4Deselect (ISO14443 4 DESELECT PARAM deselect param)
Structure with general internal operation parameters: This bit instructs the EXCHANGE function to
accept a further filled user buffer for data transfer to the PICC. If set, the function continues chaining
to the PICC with the following call. This makes two or more subsequent calls appear as one from the
PICCs point of view. OR this value into the flags member of EXCHANGE PARAM.
Definition at line 82 of file iso14443 4.h.
Parameter structure for Presence Check functionality. Has the same parameters as the DESELECT
command.
Definition at line 722 of file rclstruct.h.
This function is embedding-software defined and called by the protocol when there is the need to
set the timeout to an extended value (WTX) in order to allow the card to do more time-consuming
processing before returning data.
If the pointer is set to NULL, the protocol ignores the call and continues operation. In any other case
the pointer is considered valid.
Definition at line 798 of file rclstruct.h.
This function is embedding-software defined and called by the protocol when there is the need to set
the bitrate of the PCD, e.g. when using higher baudrates. In general, this function is called before
each communication cycle. The action taken upon this depends on the applications implementation.
If the pointer is set to NULL, the protocol ignores the call and continues operation. In any other case
the pointer is considered valid.
Definition at line 808 of file rclstruct.h.
Parameters:
cif [in] C object interface structure, see rclstruct.h
p td [in] Pointer to the Communication Parameters structure.
p lower [in] Pointer to the underlying layers TRx function.
This function binds the pre-allocated interface Component structure to its internal variables - con-
taining structure. Additionally the lower-edge interface pointer is required by this function.
Examples:
Iso14443 4 ReaderC.c.
Parameters:
set cb param [in] Pointer to a ISO14443 4 SET CB PARAM structure, defined in rclstruct.h.
The function initialises the callback pointers to embedding software-defined functionality
responsible for the application of reader settings.
The function pointers in the set cb param must point to valid locations or NULL. A detailed descrip-
tion is listed in rclstruct.h .
Parameters:
cif [in] C object interface structure, see rclstruct.h.
p protocol param [in] Pointer to a ISO14443 4 PROTOCOL PARAM structure which holds
the already initialised items the communication protocol requires for operation. The function
generates a copy of the values.
max retry [in] Number of retry attempts before the protocol bails out responding to communi-
cation errors.
This function applies the session parameters (determined during activation) to the communication
protocol. See rclstruct.h .
Parameters:
cif [in/out] C object interface structure, see rclstruct.h.
This function sets the protocol to initial state. The SetProtocolParameters() function internally calls
this method. Use for protocol-reinitialisation only - when ended up in an unrecoverable communication
error condition, for example.
Parameters:
exchange param [in/out] Parameter structure, see rclstruct.h .
Returns:
RCLSTATUS code.
Data exchange protocol according to ISO 14443-4. The exchange param of type ISO14443 4 -
EXCHANGE PARAM is described en detail in rclstruct.h .
Parameters:
presence check param [in/out] Parameter structure, see rclstruct.h .
Returns:
RCLSTATUS code.
This function checks the presence of a PICC in the field without altering its state. This is done by
exploiting the scenarios in response to a R(NACK) block.
Parameters:
deselect param [in/out] Parameter structure, see rclstruct.h .
Returns:
RCLSTATUS code.
2.12 ID Manger
The ID-Manager Component is intended as an auxiliary device for the ISO 14443-4 protocol. Both
protocols use logical IDs for communication with their conterparts (Smart Card). While the name is
different (CID in ISO 14443-4) the rules are the same. An application or calling software can choose
randomly an ID ranging from 1 to 14. ID 15 is reserved. ID 0 is, by definition the last ID to initialise.
According to the rules, the ID ZERO prevents, as long as it is occupied, further cards to be acquired
and put into the protocol flow. The ID manager has these rules built in. For example, the GetFreeID
function wont return ID ZERO as long as it finds free entries within 1..14. Consequently, no ID is
returned if ZERO is alread in use.
This component is designed to be independent from the RF chip hardware and the I/O subsystem.
Note:
For detailed information about the components, structures and parameters see this chapter or
follow the links to the source files.
Data Structures
struct RCL IDMAN PARAM
struct C RCL ID MANAGER
struct IDMAN PARAMETERS
Typedefs
Functions
RCLSTATUS IdmanInitialise (C RCL ID MANAGER cif, IDMAN PARAMETERS p td)
RCLSTATUS IdmanGetFreeID (RCL IDMAN PARAM idman param)
RCLSTATUS IdmanIsFreeID (RCL IDMAN PARAM idman param)
RCLSTATUS IdmanAssignID (RCL IDMAN PARAM idman param)
RCLSTATUS IdmanFreeIDByNumber (RCL IDMAN PARAM idman param)
RCLSTATUS IdmanFreeIDByInstance (RCL IDMAN PARAM idman param)
Parameters:
cif [in] C object interface structure, see rclstruct.h
p td [in] Pointer to the IDMAN PARAMETERS Parameters structure (pre-allocated).
Returns:
RCLSTATUS code.
This function initialises the C-object of the IdMan Component and expects valid pointers to the
internal parameters structure as well as to a pre-allocated Component structure, (rclstruct.h).
Parameters:
idman param [in] Parameter structure, defined in rclstruct.h , for ID Manager actions. The
ID member of the structure contains the free ID number. The instance and ID members
can be left dangling.
Returns:
RCLSTATUS code.
The Get Free ID function returns the first free ID in its parameter idman param. First ID 1..14
are searched, finally the function examines ID 0 if all other IDs are occupied.
Parameters:
idman param [in/out] Parameter structure, defined in rclstruct.h , for ID Manager actions.
The ID to examine must be supplied by the caller in the ID member. The instance member
can be left dangling.
Returns:
RCLSTATUS code.
Parameters:
idman param [in] Parameter structure, defined in rclstruct.h , for ID Manager actions. The
caller has to specify the address of the protocol object operating under a certain ID. Both
members, instance and ID must be initialised by the caller.
Returns:
RCLSTATUS code.
This function binds an ID to the corresponding address of the object operating unter this logical
number.
Parameters:
idman param [in] Parameter structure, defined in rclstruct.h , for ID Manager actions. The
caller must specify the ID to clear in the ID member of the parameter. The instance member
can be left dangling.
Returns:
RCLSTATUS code.
By specifying an ID number the function deletes the corresponding protocol object entry.
Parameters:
idman param [in] Parameter structure, defined in rclstruct.h , for ID Manager actions. The
caller must specify the instance to clear in the instance member of the parameter. The ID
member can be left dangling.
Returns:
RCLSTATUS code.
The ID under which the object (instance address) is listed becomes available again.
Success Indicator,
other Errors.
export LD LIBRARY PATH=. // Tell the application where to find the library
./CExample 1 /dev/ttyS0 // Start the ExampleApp (Example: Mifare Reader, First Serial Port)
C++ - ExampleProject
make cpplib // Generate the BFL
Note:
If the Linux implementation is used, the files have to be placed on top of a file system which
supports symbolic links (such as ext2, ext3, reiserfs). This is needed since the library is linked
via symbolic links.
Sometimes the Linux implementation has problems with the case senstivity of filenames. If
the project cannot be compiled, it is very likely that (due to the copy operation from the case
insensitive to the case senstive file system) some of the directories are incorrect regarding case
sensitivity. This can be either resolved by modifying the Makefile (preferred) of by modifying the
filenames themselves.
The application and the library is built as debug version. Optimization on size and speed can
be done by disabling the approprate flags (In Linux the CXXOPTIONS can be used to specify if
the library should contain debug info or not.
Since the ExampleProject does not use very system specific calls, the application should also run
on similar platforms like Windows XP, SuSE Linux, ....
Data Fields
unsigned char bus data
void self
[in/out] Data to write to (BAL WRITEBUS PARAM) / read from (BAL READBUS PARAM) the
periperal (RF chip) via the connecting bus.
Definition at line 82 of file rclstruct.h.
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Should be left dangling when calling the C++ wrapper.
Definition at line 85 of file rclstruct.h.
3.2 C BAL Struct Reference 39
C-interface structure of BUS ABSTRACTION LAYER (BAL). The BAL takes away the need to
be aware of the bus-interface specifics from upper layers. Usually the BAL is the lowest layer /
component of the RCL stack. In most cases, the bal can be omitted. Sometimes however it can be
useful, especially when using the RS 232 serial lnk.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Data Fields
C BAL WRITEBUS WriteBus
C BAL READBUS ReadBus
void mp Members
void mp CallingObject
Internal variables of the C-interface. Usually a structure is behind this pointer. The type of the
structure depends on the implementation requirements.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Used by the Glue-Class to reference the wrapping C++ object, calling into the C-interface.
Definition at line 119 of file rclstruct.h.
C_BAL
mp_Lower
C_RC_REG_CTL
mp_Lower
C_RC_IO
mp_Lower
C_ISO14443_4
C - Component interface of ISO 14443.4 data exchange protocol: This component does only data
exchange, card presence check and deselecting of a PICC. This is because only these three types of
functionality reflect the commonalities between ISO/IEC 14443.4 PICC type A and B. Protocol entry
functionality is only provided for PICC type A, however by a different interface, namely C ISO14443 -
4A ACTIVATION .
Examples:
Iso14443 4 ReaderC.c.
Data Fields
ISO14443 4 EXCHANGE Exchange
ISO14443 4 PRESENCE CHECK PresenceCheck
ISO14443 4 DESELECT Deselect
ISO14443 4 SET PROTOCOL PARAMS SetProtocolParams
ISO14443 4 RESET PROTOCOL ResetProtocol
ISO14443 4 CB SET WTX CbSetWtx
ISO14443 4 CB SET READER PARAMS CbSetReaderParams
ISO14443 4 SET CB SetCallbacks
void mp Members
void mp CallingObject
void mp CppWrapper
C RC IO mp Lower
Examples:
Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 ReaderC.c.
Deselect function.
Examples:
Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 ReaderC.c.
Internal variables of the C-interface. Usually a structure is behind this pointer. The type of the
structure depends on the implementation requirements.
Definition at line 860 of file rclstruct.h.
Used by the Glue-Class to reference the wrapping C++ object, calling into the C-interface.
Definition at line 864 of file rclstruct.h.
Used, if wrapped by the C++ feature. This location stores the C++ objects address in order to be
available for the C-only feature for handing it over to a callback or the like.
Definition at line 866 of file rclstruct.h.
C_BAL
mp_Lower
C_RC_REG_CTL
mp_Lower
C_RC_IO
mp_Lower
C_ISO14443_4A_ACTIVATION
C - Component interface of ISO 14443.4 PICC type A protocol entry. In the context of ISO 14443.4
this library exposes the PICC type A protocol entry with RATS and PPS. This component comes
without the ISO 14443.3 part (Initialisation and Anticollision) since that part is covered by a different
component. Moreover, this part initialises the ISO14443 4 PROTOCOL PARAM to be handed over
to the ISO 14443.4 transmission protocol.
Examples:
Iso14443 4 ReaderC.c.
Data Fields
ISO14443 4 RATS Rats
ISO14443 4 PPS Pps
unsigned short m trx buffer size
void mp Members
void mp CallingObject
C RC IO mp Lower
Examples:
Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 ReaderC.c.
Buffer size for frames composed by the activation. Typical values are 64, 128 or 256[Bytes]
Definition at line 951 of file rclstruct.h.
Internal variables of the C-interface. Usually a structure is behind this pointer. The type of the
structure depends on the implementation requirements.
Definition at line 955 of file rclstruct.h.
Used by the Glue-Class to reference the wrapping C++ object, calling into the C-interface.
Definition at line 959 of file rclstruct.h.
C_BAL
mp_Lower
C_RC_REG_CTL
mp_Lower
C_ISO_14443_3A
C - Component interface: Structure to call ISO 14443 Part 3 Type A functionality. ISO 14443.3
functionality represents PICC Initialisation and Anticollision as well as Halt.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Data Fields
RCL SET WAIT EVENT CB SetWaitEventCb
REQUESTA RequestA
ANTICOLLISIONSELECT AnticollisionSelect
SELECT Select
HALTA HaltA
void mp Members
void mp CallingObject
void mp UserRef
RCL WAIT EVENT CB mp WaitEventCB
C RC REG CTL mp Lower
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Examples:
MifareReaderC.c.
Internal variables of the C-interface. Usually a structure is behind this pointer. The type of the
structure depends on the implementation requirements.
Definition at line 542 of file rclstruct.h.
Used by the Glue-Class to reference the wrapping C++ object, calling into the C-interface.
Definition at line 546 of file rclstruct.h.
[in] User reference. RCL WAIT EVENT CB receives this value with the parameter structure RCL -
WAIT EVENT CB PARAM.
Definition at line 552 of file rclstruct.h.
[in] Pointer to the event-detecting callback function, to be implemented by the embedding SW.
Definition at line 554 of file rclstruct.h.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Data Fields
unsigned char m InitiatorNotTarget
I: Initiator access
Definition at line 57 of file iso14443 3 joiner.h.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Data Fields
unsigned char m InitiatorNotTarget
I: Initiator access
Definition at line 50 of file rcio joiner.h.
Internal control variables: Up until now there are no internals to keep track of. However, in order to be
ready for future extensions possibly requiring some internal variables to temporarly store information
the structure already exists.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Data Fields
unsigned char dummy
dummy variable
Definition at line 52 of file rcopctl joiner.h.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Data Fields
void com handle
unsigned char reverse bit order
For the current implementation we require a handle to the PC-RS232 link: For other implementations
different parameters may be required.
Definition at line 52 of file bal joiner rs232 pc.h.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Data Fields
unsigned char shl address
For the current implementation we require a flag which indicates the members to shift left the address
of the register by one position, as required by the test-chip.
Definition at line 50 of file rcregctl joiner rs232 pc.h.
Internal control variables: This structure holds all component-related variables and is referenced by
the mp Members element of C MIFARE READER.
Examples:
MifareReaderC.c.
Data Fields
unsigned char m TrxBuffer
The TX/RX buffer used for underlying operations. Since the minimum size of this buffer is specified
to be 64 bytes no length information needs to be present because all Mifare requests / responses are
well below this boundary.
Definition at line 93 of file mifare.h.
C_BAL
mp_Lower
C_RC_REG_CTL
mp_Lower
C_RC_IO
mp_Lower
C_MIFARE_READER
Examples:
MifareReaderC.c.
Data Fields
MIFARE GENERIC SINGLE GenericSingle
MIFARE GENERIC DOUBLE GenericDouble
MIFARE CMD Transaction
void mp Members
void mp CallingObject
C RC IO mp Lower
Examples:
MifareReaderC.c.
Internal variables of the C-interface. Usually a structure is behind this pointer. The type of the
structure depends on the implementation requirements.
Definition at line 629 of file rclstruct.h.
Used by the Glue-Class to reference the wrapping C++ object, calling into the C-interface.
Definition at line 633 of file rclstruct.h.
C_BAL
mp_Lower
C_RC_REG_CTL
mp_Lower
C_RC_IO
C - Component interface: Structure to call RC/IO functionality: The RC-I/O component is respon-
sible for all transparent I/O operations and other I/O commands of the RF chip. The layer of this
component is the topmost of the hardware-depending layers. This component is required by protocols
(e.g. Mifare, ISO 14443.4) to perform I/O operations.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Data Fields
RCL SET WAIT EVENT CB SetWaitEventCb
C RCIO TRANSCEIVE Transceive
C RCIO TRANSMIT Transmit
C RCIO RECEIVE Receive
C RCIO MFAUTHENT MfAuthent
void mp Members
void mp CallingObject
void mp UserRef
RCL WAIT EVENT CB mp WaitEventCB
C RC REG CTL mp Lower
Internal variables of the C-interface. Usually a structure is behind this pointer. The type of the
structure depends on the implementation requirements.
Definition at line 439 of file rclstruct.h.
Used by the Glue-Class to reference the wrapping C++ object, calling into the C-interface.
Definition at line 443 of file rclstruct.h.
[in] User reference. RCL WAIT EVENT CB receives this value with the parameter structure RCL -
WAIT EVENT CB PARAM.
Definition at line 449 of file rclstruct.h.
[in] Pointer to the event-detecting callback function, to be implemented by the embedding SW.
Definition at line 451 of file rclstruct.h.
C_BAL
mp_Lower
C_RC_REG_CTL
mp_Lower
C_RC_OP_CTL
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Data Fields
RCL SET WAIT EVENT CB SetWaitEventCb
C RCOPCTL GETATR SetAttrib
C RCOPCTL GETATR GetAttrib
void mp Members
void mp CallingObject
void mp UserRef
RCL WAIT EVENT CB mp WaitEventCB
C RC REG CTL mp Lower
Internal variables of the C-interface. Usually a structure is behind this pointer. The type of the
structure depends on the implementation requirements.
Definition at line 312 of file rclstruct.h.
Used by the Glue-Class to reference the wrapping C++ object, calling into the C-interface.
Definition at line 316 of file rclstruct.h.
[in] User reference. RCL WAIT EVENT CB receives this value with the parameter structure RCL -
WAIT EVENT CB PARAM.
Definition at line 322 of file rclstruct.h.
[in] Pointer to the event-detecting callback function, to be implemented by the embedding SW.
Definition at line 324 of file rclstruct.h.
C_RC_REG_CTL
C_BAL
mp_Lower
C-interface structure of register access functionality. The Register Control interface is the basic RC-
related interface. It allows access of RC registers and their bits. This component is the most versatile,
but least specific one. Usually this component is the lowest one.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Data Fields
C RC REG CTL SETREG SetRegister
C RC REG CTL GETREG GetRegister
C RC REG CTL MODREG ModifyRegister
void mp Members
void mp CallingObject
C BAL mp Lower
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Internal variables of the C-interface. Usually a structure is behind this pointer. The type of the
structure depends on the implementation requirements.
Definition at line 194 of file rclstruct.h.
Used by the Glue-Class to reference the wrapping C++ object, calling into the C-interface.
Definition at line 198 of file rclstruct.h.
Data Fields
RCL IDMAN MEMBER GetFreeID
RCL IDMAN MEMBER IsFreeID
RCL IDMAN MEMBER AssignID
RCL IDMAN MEMBER FreeIDByNumber
RCL IDMAN MEMBER FreeIDByInstance
void mp Members
void mp CallingObject
Internal variables of the C-interface. Usually a structure is behind this pointer. The type of the
structure depends on the implementation requirements.
Definition at line 1013 of file rclstruct.h.
Used by the Glue-Class to reference the wrapping C++ object, calling into the C-interface.
Definition at line 1017 of file rclstruct.h.
Internal control variables: This structure holds all component-related variables and is referenced by
the mp Members element of C RCL ID MANAGER.
Definition at line 50 of file idman.h.
Data Fields
void mp Instances [MAX ID COUNT]
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Data Fields
unsigned char sel lv1 code
unsigned char uid
unsigned char uid length
unsigned char sak
void self
[in] Select code for 1st cascade level according to ISO 14443-3. default: 0x93
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
[out] Select Acknowledge byte from the Card (if cascaded, only last SAK byte is returned).
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Remark: Should be left dangling when calling the C++ wrapper.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Parameter structure for Halt functionality. The HaltA function moves an ISO 14443-3 Type A PICC
out of protocol in Initator/Reader mode and checks if the incoming data according to Halt format in
Target/Card mode.
Examples:
MifareReader.cpp, and MifareReaderC.c.
Data Fields
unsigned char buffer
unsigned short buffer length
void self
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Remark: Should be left dangling when calling the C++ wrapper.
Examples:
MifareReaderC.c.
Parameter structure for Request functionality. The RequestA function issues a REQA or WUPA
request, depending on the req code parameter.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Data Fields
unsigned char req code
unsigned char atq
void self
[in] Request code according to ISO 14443-3. Possible values are ISO14443 3 REQIDL (0x26) and
ISO14443 3 REQALL (0x52).
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Remark: Should be left dangling when calling the C++ wrapper.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Parameter structure for SET BITRATE CALLBACK functionality. The callback function expects a
pointer to this parameter.
Definition at line 753 of file rclstruct.h.
Data Fields
void object
unsigned char dri
unsigned char dsi
unsigned char fwi
[in] Divisor Recive Integer, as specified by ISO/IEC 14443-4, determining the bitrates used from PICC
to PCD.
Definition at line 760 of file rclstruct.h.
[in] Divisor Send Integer, as specified by ISO/IEC 14443-4, determining the bitrates used from PCD
to PICC.
Definition at line 762 of file rclstruct.h.
[in] Frame waiting time-i: This value has to be applied according to ISO 14443-4 to the reader by the
application-defined callback function.
Definition at line 764 of file rclstruct.h.
Parameter structure for the SET WTX CALLBACK function. The callback function expects a pointer
to this parameter.
Definition at line 729 of file rclstruct.h.
Data Fields
void object
unsigned char set
unsigned char wtxm
unsigned char fwi
[in] Boolean value: If set it indicates that the value specified in the wtxm parameter member shall be
applied.
If zero, the timeout shall be reset to the default and the value in wtxm is not valid.
Definition at line 736 of file rclstruct.h.
[in] WTXM, encoded as specified by ISO 14443-4. This value has to be applied according to ISO
14443-4 to the reader by the application-defined callback function.
Definition at line 740 of file rclstruct.h.
[in] Frame waiting time-i: This value has to be applied according to ISO 14443-4 to the reader by the
application-defined callback function.
Definition at line 743 of file rclstruct.h.
Examples:
Iso14443 4 ReaderC.c.
Data Fields
unsigned char mp TRxBuffer
unsigned short m MaxTRxBufferSize
unsigned char m DSI
unsigned char m DRI
unsigned char m CID
unsigned char m NAD
unsigned char m Flags
unsigned char m State
unsigned char m BlockNumber
unsigned char mp CopyBytes
unsigned char mp StartOfBlock
unsigned char m MaxRetryCounter
unsigned char m FWI
unsigned char m Index
unsigned char m Size
System-mamaged TRx buffer reference, used for internal APDU composition / analysis.
Definition at line 94 of file iso14443 4.h.
Contains information about CID/NAD support by the PCD/PICC as well as their usage. Furthermore
this byte controls the internal flow in connection with e.g. timeout or chaining.
Definition at line 101 of file iso14443 4.h.
Pointer to indicate the protocol where the current block to transfer starts.
Definition at line 109 of file iso14443 4.h.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Data Fields
void self
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Should be left dangling when calling the C++ wrapper.
Examples:
Iso14443 4 ReaderC.c.
Parameter structure for Data Exchange functionality. The function for data exchange in the ISO/IEC
14443.4 protocol takes a pointer to this structure. The buffers for sending and receiving may overlap
or even be the same.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Data Fields
unsigned char nad send
unsigned char snd buf
unsigned long snd buf len
unsigned char nad receive
unsigned char rec buf
unsigned long rec buf len
unsigned char flags
void self
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
[in] A large (64k) buffer which must be pre-allocated and initialised with the data to send.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
[out] A large (64k) buffer which must be pre-allocated is the destination for data to receive.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
[in] Number of bytes available in the receive buffer: The function checks this value against the number
of bytes being received. In case of insufficient space the function breaks and returns an error.
[out] Number of bytes received from the PICC.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
[in/out] Contains flags to control the behaviour of Exchange. The flag masks are defined in iso14443 -
4.h .
Definition at line 697 of file rclstruct.h.
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Should be left dangling when calling the C++ wrapper.
Examples:
Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Data Fields
unsigned char cid
unsigned char dsi
unsigned char dri
void self
[in] CID assigned to the PICC. The function checks the range.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
[in] Dividor Send Integer: ISO/IEC 14443.4 reference value for baud rate used when sending data to
the PICC.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
[in] Dividor Receive Integer: ISO/IEC 14443.4 reference value for baud rate used when receiving data
from the PICC.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Should be left dangling when calling the C++ wrapper.
Examples:
Iso14443 4 ReaderC.c.
Structure for ISO/IEC 14443.4 data transmission protocol initialisation. This structure has to be
handed over to the protocol component instance prior to communication and after PICC protocol
entry. The purpose is to inform the data exchange protocol about the PICC and Reader properties
(parameters) to use during communication.
This structure is filled automatically be the protocol entry interface C ISO14443 4A ACTIVATION
for type A PICCs but has to be initialised member-by-member when operating type B PICCs.
Examples:
Iso14443 4 ReaderC.c.
Data Fields
unsigned char trx buffer
unsigned short trx buffer size
unsigned char cid supported
unsigned char nad supported
unsigned char cid
unsigned char tx baud int
unsigned char rx baud int
unsigned char fwi
[in] Pointer to a pre - allocated TX/RX buffer. This buffer is used by the protocol for data exchange
frame composition and handed over to the underlying I/O features (RC-I/O).
Definition at line 658 of file rclstruct.h.
[in] Buffer size for frames composed by the protocol. Typical values are 64, 128 or 256 [bytes].
Definition at line 661 of file rclstruct.h.
[in] A value other than zero (TRUE) indicates that CID is supported and shall be used by the protocol.
Definition at line 663 of file rclstruct.h.
[in] A value other than zero (TRUE) indicates that NAD is supported and shall be used by the
protocol.
Definition at line 665 of file rclstruct.h.
[in] If CID is supported this value will be inserted into the CID field of exchanged frames.
Definition at line 667 of file rclstruct.h.
[in] ISO/IEC 14443.4 definitions for the baud rate (DSI) used for sending information to the PICC.
Definition at line 669 of file rclstruct.h.
[in] ISO/IEC 14443.4 definitions for the baud rate (DRI) used for receiving information from the
PICC.
Definition at line 671 of file rclstruct.h.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Data Fields
unsigned char cid
unsigned char fsi
unsigned char ats
unsigned short ats len
unsigned char ta1
unsigned char tb1
unsigned char tc1
unsigned char app inf
unsigned char app inf len
void self
[in] CID assigned to the PICC. The function only checks the range, but not the rules in the context
of the value 0.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
[in] FSDI, the PCD frame size integer, according to ISO/IEC 14443.4.
[out] FSDI, the PCD frame size integer, according to ISO/IEC 14443.4.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
[in/out] Pointer to a pre-allocated buffer receiving the ATS. The size of the buffer has to comply to
the ISO/IEC 14443.4 - defined maximum size of the ATS.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
Examples:
Iso14443 4 Reader.cpp, and Iso14443 4 ReaderC.c.
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Should be left dangling when calling the C++ wrapper.
Examples:
Iso14443 4 ReaderC.c.
Parameter structure for the function for setting the callback addresses.
Definition at line 815 of file rclstruct.h.
Data Fields
ISO14443 4 CB SET WTX set wtx cb
ISO14443 4 CB SET READER PARAMS set reader params cb
void self
[in] Pointer to the callback function handling the WTX request. If NULL, the protocol operates
without WTX capability.
Definition at line 817 of file rclstruct.h.
[in] Pointer to the callback function handling the bitrate switching. If NULL, the protocol operates
without bitrate changing capability.
Definition at line 820 of file rclstruct.h.
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Should be left dangling when calling the C++ wrapper.
Definition at line 823 of file rclstruct.h.
Examples:
MifareReader.cpp, and MifareReaderC.c.
Data Fields
unsigned char cmd
unsigned char addr
unsigned char buffer
unsigned char buffer length
unsigned char reply type
void self
Examples:
MifareReader.cpp, and MifareReaderC.c.
[in] MIFARE block address: MIFARE operates block-oriented, although authentication is sector-
based.
Examples:
MifareReader.cpp, and MifareReaderC.c.
[in] For sending bytes this must be a pre-allocated and initialised buffer. For receiving data, the buffer
must be pre-allocated and of a size of MIFARE MAX DATABUFFER SIZE, defined in mifare.h .
[out] Data copied into the buffer by this function e.g. as a result of a READ operation.
Examples:
MifareReader.cpp, and MifareReaderC.c.
[in] Length of data to send: Usually this value is 16 for a block to write.
For a READ operation this value should be initialised with 0.
[out] Receive buffer length: Number of data bytes received.
Examples:
MifareReader.cpp, and MifareReaderC.c.
[in] When using the Transaction member of the MIFARE functionality this parameter should be left
dangling.
When using the generic Mifare methods, this parameter specifies what type of response (none or
timeout respectively, acknowledge or data) to expect.
Definition at line 599 of file rclstruct.h.
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Should be left dangling when calling the C++ wrapper.
Examples:
MifareReaderC.c.
Parameter structure for Receive functionality. This structure reflects a transparent Receive channel.
The Receive function enters wait mode and finally returns after all bytes have been received or an
error (e.g. timeout) occurs.
Definition at line 388 of file rclstruct.h.
Data Fields
unsigned char rx buffer
unsigned short rx buffer size
void self
[in] Already allocated memory space sufficiently large to receive incoming data.
[out] Data copied to the provided buffer.
Definition at line 390 of file rclstruct.h.
[in] Maximum return buffer size in bytes. This member informs the function about the size of the
buffer for incoming data. The function checkes the buffer boundaries and returns an error in case of
too many bytes being returned by the underlying features.
[out] Yields the number of bytes actually returned.
Definition at line 393 of file rclstruct.h.
[in] Pointer to the C-interface in order to let this member function find its object. Should be left
dangling when calling the C++ wrapper.
Definition at line 398 of file rclstruct.h.
Parameter structure for Transceive functionality. The members of this structure reflect a simple
transparent I/O channel through lower layers and finally the chip. The Transceive function (which
takes this structure as its parameter) always waits for I/O completion (all bytes received or error
encountered (e.g. timeout). No overlapped Transceive operation is possible. The send- and receive-
buffers may overlap or even be the same, no double-buffering is required.
Definition at line 344 of file rclstruct.h.
Data Fields
unsigned char tx buffer
unsigned short tx buffer size
unsigned char rx buffer
unsigned short rx buffer size
void self
[in] References data to transmit via the UART. The location referenced must contain an initialised
buffer holding the data to transmit. The maximum size of the buffer depends on the underlying
systems capabilities regarding how many bytes it can transmit in one frame.
Definition at line 346 of file rclstruct.h.
[in] Already allocated memory space sufficiently large to receive incoming data.
[out] Data copied to the provided buffer.
Definition at line 352 of file rclstruct.h.
[in] Maximum return buffer size in bytes. This member informs the function about the size of the
buffer for incoming data. The function checkes the buffer boundaries and returns an error in case of
too many bytes being returned by the underlying features.
[in] Pointer to the C-interface in order to let this member function find its object. Should be left
dangling when calling the C++ wrapper.
Definition at line 360 of file rclstruct.h.
Parameter structure for Transmit functionality. This structure reflects a transparent Transmit chan-
nel. The Transmit function returns after all bytes have been sent.
Definition at line 369 of file rclstruct.h.
Data Fields
unsigned char tx buffer
unsigned short tx buffer size
void self
[in] References data to transmit via the UART. The location referenced must contain an initialised
buffer holding the data to transmit. The maximum size of the buffer depends on the underlying
systems capabilities regarding how many bytes it can transmit in one frame.
Definition at line 371 of file rclstruct.h.
[in] Pointer to the C-interface in order to let this member function find its object. Should be left
dangling when calling the C++ wrapper.
Definition at line 377 of file rclstruct.h.
Data Fields
unsigned char ID
void instance
void self
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Should be left dangling when calling the C++ wrapper.
Definition at line 983 of file rclstruct.h.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Data Fields
unsigned char group ordinal
unsigned char attrtype ordinal
unsigned char param a
unsigned char param b
unsigned char buffer
void self
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
[in] Pointer to the C-interface in order to let this member function find its object. Should be left
dangling when calling the C++ wrapper.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Data Fields
unsigned char address
unsigned char mask
unsigned char set
void self
[in] References a register location within the RF chip. This member is not modified by the func-
tion.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
[in] A mask, specifying which register bits to modify. While bits set to one in the mask are touched
in the register, those set to zero remain unchanged.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
[in] Type of operation - Set = 1, Clear = 0. The bits set to one in the mask are modified in the
register, according to the value of this member.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Should be left dangling when calling the C++ wrapper.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
Data Fields
unsigned char address
unsigned char reg data
void self
[in] References a register location within the RF chip. This member is not modified by the func-
tion.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
[in/out] Data to write to (or read from - see RCREGCTL GETREG PARAM) the specified regis-
ter.
Examples:
Iso14443 4 Reader.cpp, Iso14443 4 ReaderC.c, MifareReader.cpp, and MifareReaderC.c.
[in] Pointer to the C-interface of this component in order to let this member function find its object.
Should be left dangling when calling the C++ wrapper.
Examples:
Iso14443 4 ReaderC.c, and MifareReaderC.c.
#define MAX_BUFFER_SIZE 64
/* Common headers */
#include <joinerreg.h>
#include <rclstruct.h>
/*
* This example shows how to act as ISO14443-4 reader
*/
int ActivateIso14443_4_Reader(int comHandle)
{
/* BAL either for Windows xor for Linux */
#ifdef WIN32
4.1 Iso14443 4 Reader.cpp 100
Bal<C_JOINER_RS_232_PC_BAL_PARAMS> bal;
#else
Bal<C_JOINER_RS_232_LINUX_BAL_PARAMS> bal;
#endif
RcRegCtl<C_JOINER_RS_232_PC_RC_REG_CTL_PARAMS> rc_reg_ctl;
RcIo<C_JOINER_RC_IO_PARAMETERS> rcio;
RcOpCtl<C_JOINER_RC_OP_CTL_PARAMETERS> rc_op_ctl;
Iso14443_3<C_JOINER_ISO_14443_3_PARAMETERS> iso14443_3;
Iso14443_4A_Activation iso14443_4A;
Iso14443_4 iso14443_4;
/* ISO14443-3A parameters */
ISO14443_3_REQUEST_A_PARAM req_p;
ISO14443_3_ANTICOLLISIONSELECT_PARAM sel_p;
/*
* Generic variables
*/
RCLSTATUS status = RCLSTATUS_SUCCESS;
/* Buffer for data transfer (send/receive) */
unsigned char buffer[MAX_BUFFER_SIZE];
/* Buffer serial number */
unsigned char serial[12];
/* Counter variable */
unsigned char i;
/* Mifare EvalOS command to read data from Mifare EEProm area using PasswordRead function */
unsigned char readMFblock [14] = { 0xB8, 0x80, 0x04, 0x00, 0x08, 0x0b, 0x54, 0x57, 0x07, 0x45, 0xfe,
0x3a, 0xe7, 0x10 };
unsigned char rcvBuf[MAX_BUFFER_SIZE];
unsigned char ats[MAX_BUFFER_SIZE];
/* Let the BAL know about the used serial Port which is initialised outside of this function */
#ifdef WIN32
((C_JOINER_RS_232_PC_BAL_PARAMS*)bal.m_Interface.mp_Members)->com_handle = (void*) comHandle;
#else
((C_JOINER_RS_232_LINUX_BAL_PARAMS*)bal.m_Interface.mp_Members)->com_handle = comHandle;
#endif
/*
* Configure RC522 to act as a Mifare Reader. All register which are set in other modes
* are configured to the right values.
* Remark: Operation control function do not perform a softreset and does not know anything
* about the antanne configuration, so these things have to be handled here!
*/
opp.group_ordinal = RCO_GROUP_MODE;
opp.attrtype_ordinal = RCO_ATTR_MFRD_A;
opp.param_a = RCO_VAL_RF106K;
opp.param_b = RCO_VAL_RF106K;
status = rc_op_ctl.SetAttrib(&opp);
/* Check status and display error if something went wrong */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR performing Mifare Reader configuration! Status = %04x \n", status);
/*
* Set the timer to auto mode, 5ms using operation control commands before HF is
* switched on to guarantee Iso14443-3 compliance of the polling procedure
*/
opp.group_ordinal = RCO_GROUP_TIMER; /* Set operation control group parameter to Timer */
opp.attrtype_ordinal = RCO_ATTR_TIMER_AUTO; /* Set function for Timer automatic mode */
opp.param_a = RCO_VAL_TIMER_AUTO_ON; /* Use parameter a to switch it on */
status = rc_op_ctl.SetAttrib(&opp);
/* Check status and display error if something went wrong */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! OperationControl settings Timer auto mode. Status = %04x \n", status);
/*
* Set prescaler steps to 100us
*/
opp.group_ordinal = RCO_GROUP_TIMER;
opp.attrtype_ordinal = RCO_ATTR_TIMER_PRESCALER;
/* Calculation of the values: 100us = 6.78MHz/678 = 6.78MHz/0x2A6 */
opp.param_a = 0xA6; /* Low value */
opp.param_b = 0x02; /* High value */
status = rc_op_ctl.SetAttrib(&opp);
/* Check status and display error if something went wrong */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! OperationControl settings Timer Prescaler. Status = %04x \n", status);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! ModifyRegister: Set=%1d, Address=%02X, Mask=%02X, Status = %04x \n",
mrp.set, mrp.address, mrp.mask, status);
/*
* After switching on the timer wait until the timer interrupt occures, so that
* the field is on and the 5ms delay have been passed.
*/
grp.address = JREG_COMMIRQ;
do {
status = rc_reg_ctl.GetRegister(&grp);
}
while(!(grp.reg_data & JBIT_TIMERI) && status == RCLSTATUS_SUCCESS);
/* Check status and diplay error if something went wrong */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! GetRegister: Address=%02X, Data=02X, Status = %04x \n",
grp.address, grp.reg_data, status);
/*
* Reset timer 1 ms using operation control commands (AutoMode and Prescaler are the same)
* set reload value
*/
opp.group_ordinal = RCO_GROUP_TIMER; /* set operation control group parameter to Timer */
opp.attrtype_ordinal = RCO_ATTR_TIMER_RELOAD; /* set to 10 for 1 ms */
opp.param_a = 10; /* Low value */
opp.param_b = 0; /* High value (max 0xFF) */
status = rc_op_ctl.SetAttrib(&opp);
// check status and diplay error if something went wrong
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! OperationControl settings Timer Reload. Status = %04x \n", status);
/*
* Do activation according to ISO14443A Part3
* Prepare the Request command
*/
buffer[0] = 0;
buffer[1] = 0;
req_p.req_code = ISO14443_3_REQIDL; /* Set Request command code (or Wakeup: ISO14443_3_REQALL) */
req_p.atq = buffer; /* Let Request use the defined return buffer */
/* Example how to use the Iso14443 Part4 (T=CL) specific command set of the BFL */
else
printf("no TC(1), ");
if(rat_p.app_inf_len)
{
printf("%02X \nHistorical characters: ", rat_p.app_inf_len);
for(i=0;i<(rat_p.app_inf_len);i++)
printf("%02X ", rat_p.app_inf[i]);
} else
{
printf("\nNo Historcal characters. ");
}
printf("\n");
} else
{
printf("*** ERROR! ISO14443 Part4 -> RATS: Status = %04x \n", status);
}
/* Change data rate with PPS directly afterwards (not allowed later on) */
pps_p.cid = 0x00; /* no card identifier used */
pps_p.dri = RCO_VAL_RF106K; /* data rate PCD -> PICC */
pps_p.dsi = RCO_VAL_RF106K; /* data rate PICC -> PCD */
status = iso14443_4A.Pps(&pps_p);
if(status == RCLSTATUS_SUCCESS)
{
printf("PPS handled without errors, reconfiguration is possible.\n");
/* Call operation control function with new data rate */
opp.group_ordinal = RCO_GROUP_MODE;
opp.attrtype_ordinal = RCO_ATTR_MFRD_A;
opp.param_a = RCO_VAL_RF106K;
opp.param_b = RCO_VAL_RF106K;
/* Start set attribute command */
status = rc_op_ctl.SetAttrib(&opp);
/* Hand over parameters generated in activatin part to transparent protocol part of ISO 14443-4
Comment: this is only necessary in CPP implementation because there the struct is generated internally. */
iso14443_4.SetProtocolParameters(iso14443_4A.ProtocolParameters(), 1);
exc_p.nad_receive = 0;
exc_p.nad_send = 0;
exc_p.snd_buf = readMFblock;
exc_p.snd_buf_len = 14;
exc_p.rec_buf = rcvBuf;
exc_p.rec_buf_len = 64;
status = iso14443_4.Exchange(&exc_p);
if(status == RCLSTATUS_SUCCESS)
{
printf("Exchange handled without errors, Mifare Read OK. \n Data: ");
for (i=0; i<exc_p.rec_buf_len; i++)
printf("%02X ", exc_p.rec_buf[i]);
printf("\n");
} else
{
printf("*** ERROR! ISO14443 Part4 -> Exchange: MifareRead: Status = %04x \n", status);
}
/*
* To start a communication with a new device all internal status variables have to be reset.
*/
iso14443_4.ResetProtocol(); /* This function has no return value. All variables are reset! */
#define MAX_BUFFER_SIZE 64
/* Include all necessary component headers for Mifare Reader operation and additional definitions.
(BAL, RegisterControl, Iso14443Part3, OperationControl, RcIo, Mifare) */
/* Common headers */
#include <joinerreg.h>
#include <rclstruct.h>
/*
* This example shows how to act as ISO14443-4 reader
*/
int ActivateIso14443_4_Reader(int comHandle)
{
/* Declaration of variables, buffer, ... */
RCLSTATUS status = RCLSTATUS_SUCCESS;
/* Buffer for data transfer (send/receive) */
unsigned char buffer[64];
unsigned char rcvBuf[64];
/* Buffer serial number */
unsigned char serial[12];
/* Counter variable */
unsigned char i;
/* Buffer for ATS */
unsigned char ats[64];
unsigned char readMFblock [14] = { 0xB8, 0x80, 0x04, 0x00, 0x08, 0x0b, 0x54, 0x57, 0x07, 0x45,
0xfe, 0x3a, 0xe7, 0x10 };
/* BFL Stack */
C_BAL bal;
C_RC_REG_CTL rc_reg_ctl;
C_RC_IO rcio;
C_RC_OP_CTL rc_op_ctl;
C_ISO_14443_3A iso14443_3;
C_ISO14443_4 iso14443_4;
C_ISO14443_4A_ACTIVATION iso14443_4A;
#ifdef WIN32
C_JOINER_RS_232_PC_BAL_PARAMS bal_params;
#else
C_JOINER_RS_232_LINUX_BAL_PARAMS bal_params;
#endif
C_JOINER_RS_232_PC_RC_REG_CTL_PARAMS rc_reg_ctl_params;
C_JOINER_RC_IO_PARAMETERS rc_io_params;
C_JOINER_RC_OP_CTL_PARAMETERS rc_op_ctl_params;
C_JOINER_ISO_14443_3_PARAMETERS iso_14443_3_params;
ISO14443_3_REQUEST_A_PARAM req_p;
ISO14443_3_ANTICOLLISIONSELECT_PARAM sel_p;
/* T=CL activation parameters */
ISO14443_4_PROTOCOL_PARAM pro_p;
ISO14443_4_RATS_PARAM rat_p;
ISO14443_4_PPS_PARAM pps_p;
/* Transparent protocol operations */
ISO14443_4_EXCHANGE_PARAM exc_p;
ISO14443_4_COMMUNICATION_PARAMETERS com_p;
ISO14443_4_PRESENCE_CHECK_PARAM prs_p;
ISO14443_4_DESELECT_PARAM dsl_p;
/* Let the BAL know about the used serial Port which is initialised outside of this function */
#ifdef WIN32
/* This is for Windows */
((C_JOINER_RS_232_PC_BAL_PARAMS*) (bal.mp_Members))->com_handle = (void*) comHandle;
#else
/* And this one for Linux */
((C_JOINER_RS_232_LINUX_BAL_PARAMS*) (bal.mp_Members))->com_handle = comHandle;
#endif
grp.self = &rc_reg_ctl;
opp.self = &rc_op_ctl;
req_p.self = &iso14443_3;
sel_p.self = &iso14443_3;
rat_p.self = &iso14443_4A;
pps_p.self = &iso14443_4A;
exc_p.self = &iso14443_4;
prs_p.self = &iso14443_4;
dsl_p.self = &iso14443_4;
/* Configure RC522 to act as a Mifare Reader. All register which are set in other modes
are configured to the right values.
Remark: operation control function do not perform a softreset and does not know anything
about the antanne configuration, so these things have to be handled here! */
opp.group_ordinal = RCO_GROUP_MODE;
opp.attrtype_ordinal = RCO_ATTR_MFRD_A;
opp.param_a = RCO_VAL_RF106K;
opp.param_b = RCO_VAL_RF106K;
/* Start set attribute command */
status = rc_op_ctl.SetAttrib(&opp);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR performing Mifare Reader configuration! Status = %04x \n", status);
/* Set the timer to auto mode, 5ms using operation control commands before HF is switched on to
guarantee Iso14443-3 compliance of Polling procedure */
/* activate automatic start/stop of timer */
opp.group_ordinal = RCO_GROUP_TIMER; /* set operation control group parameter to Timer */
opp.attrtype_ordinal = RCO_ATTR_TIMER_AUTO; /* set function for Timer automatic mode */
opp.param_a = RCO_VAL_TIMER_AUTO_ON; /* use parameter a to switch it on */
/* Start set attribute command */
status = rc_op_ctl.SetAttrib(&opp);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! OperationControl settings Timer auto mode. Status = %04x \n", status);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! ModifyRegister: Set=%1d, Address=%02X, Mask=%02X, Status = %04x \n",
mrp.set, mrp.address, mrp.mask, status);
/* After switching on the timer wait until the timer Interrupt occures, so that
the field is on and the 5ms delay have been passed. */
grp.address = JREG_COMMIRQ;
do
{
status = rc_reg_ctl.GetRegister(&grp);
}
while(!(grp.reg_data & JBIT_TIMERI) && status == RCLSTATUS_SUCCESS);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! GetRegister: Address=%02X, Data=02X, Status = %04x \n",
grp.address, grp.reg_data, status);
/*
* Reset timer 1 ms using operation control commands (AutoMode and Prescaler are the same)
* set reload value */
opp.group_ordinal = RCO_GROUP_TIMER; /* set operation control group parameter to Timer */
opp.attrtype_ordinal = RCO_ATTR_TIMER_RELOAD; /* set to 10 for 1 ms */
opp.param_a = 10; /* Low value */
opp.param_b = 0; /* High value (max 0xFF) */
status = rc_op_ctl.SetAttrib(&opp);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! OperationControl settings Timer Reload. Status = %04x \n", status);
/* ---------------------------------------------------------------------------- */
/* Example how to use the Iso14443 Part4 (T=CL) specific command set of the BFL */
/* change data rate with PPS directly afterwards (not allowed later on) */
pps_p.cid = 0x00; /* no card identifier used */
pps_p.dri = RCO_VAL_RF106K; /* data rate PCD -> PICC */
pps_p.dsi = RCO_VAL_RF106K; /* data rate PCD -> PICC */
status = iso14443_4A.Pps(&pps_p);
if(status == RCLSTATUS_SUCCESS)
{
printf("PPS handled without errors, reconfiguration is possible.\n");
/* call Operation control function with new data rate */
opp.group_ordinal = RCO_GROUP_MODE;
opp.attrtype_ordinal = RCO_ATTR_MFRD_A;
opp.param_a = RCO_VAL_RF106K;
opp.param_b = RCO_VAL_RF106K;
status = rc_op_ctl.SetAttrib(&opp);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR performing Mifare Reader configuration for higher data rates! Status = %04x \n", status);
} else
{
printf("*** ERROR! ISO14443 Part4 -> PPS: Status = %04x \n", status);
}
exc_p.nad_receive = 0;
exc_p.nad_send = 0;
exc_p.snd_buf = readMFblock;
exc_p.snd_buf_len = 14;
exc_p.rec_buf = rcvBuf;
exc_p.rec_buf_len = 64;
status = iso14443_4.Exchange(&exc_p);
if(status == RCLSTATUS_SUCCESS)
{
printf("Exchange handled without errors, Mifare Read OK. \nData: ");
for (i=0; i<exc_p.rec_buf_len; i++)
printf("%02X ", exc_p.rec_buf[i]);
printf("\n");
} else
{
printf("*** ERROR! ISO14443 Part4 -> Exchange: MifareRead: Status = %04x \n", status);
}
/* To start a communication with a new device all internal status variables have to be reset. */
iso14443_4.ResetProtocol(&iso14443_4); /* This function has no return value. All variables are reset! */
return status;
}
4.3 MifareReader.cpp
The following code contains an example for implementing the Mifare Reader functionality using the
BFL.
The MifareParams function show the necessary settings of the RC522 hardware to act like a Mifare
Reader.
In the main procedure (ActivateMifareReader) first all necessary components of the BFL are declared.
After this, all relevant data structs are declared. Doing this you may start to initialise the BFL stack.
In this example the serial interface of a PC is used. The initialisation of this part is not shown in this
example. The BAL needs only to know about the interface, so the handle is set to the com handle of
the BAL.
Then everything is ready to initialise the RC522. This is done by using dedicated functions of the
operation control component.
Then a timeout value has to be defined and the first command of the activation can be started.
After successful activation there are exapmles shown how to authenticate a Mifare Card and how to
read or write data from the authenticated sector.
At the end an HaltA command is processed, to set the Card into halt state.
/* /////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Philips Semiconductors
//
// (C)PHILIPS Electronics N.V.2004
// All rights are reserved. Reproduction in whole or in part is
// prohibited without the written consent of the copyright owner.
// Philips reserves the right to make changes without notice at any time.
// Philips makes no warranty, expressed, implied or statutory, including but
// not limited to any implied warranty of merchantability or fitness for any
// particular purpose, or that the use will not infringe any third party patent,
// copyright or trademark. Philips must not be liable for any loss or damage
// arising from its use.
/* Include all necessary component headers for Mifare Reader operation and additional definitions.
(BAL, RegisterControl, Iso14443Part3, OperationControl, RcIo, Mifare) */
/* Common headers */
#include <joinerreg.h>
#include <rclstruct.h>
#include "ExampleUtils.h"
/*
* This example shows how to act as Mifare reader
*/
/* ISO14443-3A parameters */
ISO14443_3_REQUEST_A_PARAM req_p;
ISO14443_3_ANTICOLLISIONSELECT_PARAM sel_p;
ISO14443_3_HALT_A_PARAM hlt_p;
/* Mifare parameters */
MIFARE_CMD_PARAM mfr_p;
/*
* Generic variables
*/
RCLSTATUS status = RCLSTATUS_SUCCESS;
/* Buffer for data transfer (send/receive) */
unsigned char buffer[64];
/* Buffer serial number */
unsigned char serial[12];
/* Counter variable */
unsigned char i, index;
/*
* Build up stack for serial communication.
* Start with the lowest layer, so that the upper ones may refer to this already.
*/
#ifdef WIN32
bal.Initialise(JoinerBalRs232PcInitialise);
#else
bal.Initialise(JoinerBalRs232LinuxInitialise);
#endif
/* Initialise Register Control Layer component */
rc_reg_ctl.Initialise(JoinerRcRegCtlRs232PcInitialise, &bal);
/* Initialise RcIo component */
rcio.Initialise(JoinerRcIoInitialise, &rc_reg_ctl, 1);
/* Initialise Operation Control component */
rc_op_ctl.Initialise(JoinerRcOpCtlInitialise, &rc_reg_ctl);
/* initialise ISO14443-3 component */
iso14443_3.Initialise(JoinerIso14443_3Initialise, &rc_reg_ctl, ISO14443_3_INITIATOR);
/* Initialise Mifare component */
mfrd.Initialise(&rcio, buffer+20);
/* Let the BAL know about the used serial Port which is initialised outside of this function */
#ifdef WIN32
((C_JOINER_RS_232_PC_BAL_PARAMS*) (bal.m_Interface.mp_Members))->com_handle = (void*) comHandle;
#else
((C_JOINER_RS_232_LINUX_BAL_PARAMS*) (bal.m_Interface.mp_Members))->com_handle = comHandle;
#endif
/* Configure RC522 to act as a Mifare Reader. All register which are set in other modes
* are configured to the right values.
* Remark: The operation control function does not perform a softreset and does not know anything
* about the antanna configuration, so these things have to be handled separately!
*/
opp.group_ordinal = RCO_GROUP_MODE;
opp.attrtype_ordinal = RCO_ATTR_MFRD_A;
opp.param_a = RCO_VAL_RF106K;
opp.param_b = RCO_VAL_RF106K;
status = rc_op_ctl.SetAttrib(&opp);
/* Check status and display error if something went wrong */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR performing Mifare Reader configuration! Status = %04x \n", status);
/* Set the timer to auto mode, 5ms using operation control commands before HF is switched on to
* guarantee Iso14443-3 compliance of Polling procedure
*/
status = SetTimeOut(&rc_op_ctl, 5000);
/*
* After switching on the timer wait until the timer interrupt occures, so that
* the field is on and the 5ms delay have been passed.
*/
grp.address = JREG_COMMIRQ;
do {
status = rc_reg_ctl.GetRegister(&grp);
}
while(!(grp.reg_data & JBIT_TIMERI) && status == RCLSTATUS_SUCCESS);
/* Check status and diplay error if something went wrong */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! GetRegister: Address=%02X, Data=%02X, Status = %04x \n",
grp.address, grp.reg_data, status);
/*
* Reset timer 1 ms using operation control commands (AutoMode and Prescaler are the same)
* set reload value
*/
status = SetTimeOut(&rc_op_ctl, 5000);
srp.reg_data = JCMD_NOCMDCHANGE;
status = rc_reg_ctl.SetRegister(&srp);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! SetRegister: Address=%02X, Data=%02X, Status = %04x \n",
srp.address, srp.reg_data, status);
/*
* Do activation according to ISO14443A Part3
* Prepare the Request command
*/
buffer[0] = 0;
buffer[1] = 0;
req_p.req_code = ISO14443_3_REQIDL; /* Set Request command code (or Wakeup: ISO14443_3_REQALL) */
req_p.atq = buffer; /* Let Request use the defined return buffer */
status = iso14443_3.RequestA(&req_p); /* Start Request command */
/*
* In normal operation this command returns one of the following three return codes:
* - RCLSTATUS_SUCCESS At least one card has responded
* - RCLSTATUS_COLLISION_ERROR At least two cards have responded
* - RCLSTATUS_IO_TIMEOUT No response at all
*/
if(status == RCLSTATUS_SUCCESS || status == RCLSTATUS_COLLISION_ERROR)
{
/* There was at least one response */
if(status == RCLSTATUS_COLLISION_ERROR)
printf("[W] Multiple Cards detected!! Collission occured during Request!\n");
printf("ATQA = %02x %02x \n", req_p.atq[0],req_p.atq[1]);
} else
/* No response at all */
printf("*** ERROR! RequestA: RequestCode=%02X, ATQA=%02X %02X, Status = %04x \n",
req_p.req_code, req_p.atq[0],req_p.atq[1], status);
/*
* Up to this point the ISO14443-3A protocol has been used
* Now part 3 is finished and one has to choose between the several branches. Here is the
* example how to use the Mifare Standard specific command set of the BFL
*/
/* Prepare data for Mifare Read again to check what has been written */
mfr_p.cmd = MIFARE_READ;
mfr_p.addr = 0x05;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 0;
status = mfrd.Transaction(&mfr_p);
/* Check return code and display error number if an error occured, else display data */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareRead: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
{
printf("Mifare Read: Block=%02X, Data: ", mfr_p.addr);
for(i=0;i<mfr_p.buffer_length;i++)
printf("%02X",mfr_p.buffer[i]);
printf("\n");
}
/*
* Mifare Value Block operation example
*/
/*
* Prepare data for Mifare Authentication for example of Value block operation.
* The same as in the previous example.
*/
index = 6;
for(i=0;i<4;i++)
buffer[index++] = serial[i];
for(i=0;i<6;i++)
buffer[i] = 0xFF;
mfr_p.cmd = MIFARE_AUTHENT_A;
mfr_p.addr = 0x09;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 10;
status = mfrd.Transaction(&mfr_p);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! Mifare Authentication: Command=%01X, Block=%02X, Status = %04x \n",
mfr_p.cmd, mfr_p.addr, status);
else
printf("Authentication of block %02X successful, continue operation.\n", mfr_p.addr);
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 10000);
/* Init Block 9 as value block with value 100 with Mifare write
* Data in hex: 64 00 00 00 9B FF FF FF 64 00 00 00 09 F6 09 F6 */
mfr_p.cmd = MIFARE_WRITE ;
mfr_p.addr = 0x09;
mfr_p.buffer_length = MIFARE_STD_BLOCK_SIZE;
i=0;
/* init 1st 4 bytes with the specified value */
buffer[i++] = 0x64; // 0x64 == 100
buffer[i++] = 0x00;
buffer[i++] = 0x00;
buffer[i++] = 0x00;
/* 2nd 4 bytes must have bit-inverted value */
for( ; i<8; i++)
buffer[i] = (unsigned char)(~buffer[i-4]);
/* 3rd 4 bytes must have same value as 1st 4 bytes */
for( ; i<12; i++)
buffer[i] = buffer[i-8];
/* 4th 4 byte contain the address, twice plain, twice bit inverted */
buffer[i++] = mfr_p.addr;
/* Prepare data for Mifare Read again to check what has been written */
mfr_p.cmd = MIFARE_READ;
mfr_p.addr = 0x09;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 0;
status = mfrd.Transaction(&mfr_p);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareRead: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
{
printf("Mifare Read: Block=%02X, Data: ", mfr_p.addr);
for(i=0;i<mfr_p.buffer_length;i++)
printf("%02X",mfr_p.buffer[i]);
printf("\n");
}
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 5000);
SetTimeOut(&rc_op_ctl, 5000);
/* Prepare data for Mifare Read again to check what has been written with increment */
mfr_p.cmd = MIFARE_READ;
mfr_p.addr = 0x09;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 0;
/* Start Mifare Read */
status = mfrd.Transaction(&mfr_p);
/* Check return code and display error number if an error occured, else display data */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareRead: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
{
printf("Mifare Read: Block=%02X, Data: ", mfr_p.addr);
for(i=0;i<mfr_p.buffer_length;i++)
printf("%02X",mfr_p.buffer[i]);
printf("\n");
}
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 5000);
/* Prepare data for Mifare Read again to check what has been written with decrement */
mfr_p.cmd = MIFARE_READ;
mfr_p.addr = 0x09;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 0;
status = mfrd.Transaction(&mfr_p);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareRead: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
{
printf("Mifare Read: Block=%02X, Data: ", mfr_p.addr);
for(i=0;i<mfr_p.buffer_length;i++)
printf("%02X",mfr_p.buffer[i]);
printf("\n");
}
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 5000);
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 10000);
/* Prepare data for Mifare Read again to check what has been written */
mfr_p.cmd = MIFARE_READ;
mfr_p.addr = 0x08;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 0;
status = mfrd.Transaction(&mfr_p);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareRead: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
{
printf("Mifare Read: Block=%02X, Data: ", mfr_p.addr);
for(i=0;i<mfr_p.buffer_length;i++)
printf("%02X",mfr_p.buffer[i]);
printf("\n");
}
SetTimeOut(&rc_op_ctl, 10000);
mfr_p.cmd = MIFARE_WRITE4;
mfr_p.addr = 0x07;
mfr_p.buffer_length = MIFARE_UL_PAGE_SIZE;
for(i=0; i < mfr_p.buffer_length; i++)
buffer[i] = (unsigned char)(i + 0x90);
mfr_p.buffer = buffer;
*/
/* Start Mifare Write 4 */
/*
status = mfrd.Transaction(&mfr_p);
if(status != RCLSTATUS_SUCCESS)
/*
* Do ISO14443-3 HaltA for deactivation of the card
*/
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 1000);
status = iso14443_3.HaltA(&hlt_p);
/* Check return code: If timeout occures, RCLSTATUS_SUCCESS is returned */
if(status == RCLSTATUS_SUCCESS)
{
printf("Halt probably successful, timeout occured\n");
}
else
{
printf("*** ERROR! HaltA: Status = %04x \n", status);
}
return status;
}
4.4 MifareReaderC.c
The following code contains an example for implementing the Mifare Reader functionality using the
BFL.
The MifareParams function show the necessary settings of the RC522 hardware to act like a Mifare
Reader.
In the main procedure (ActivateMifareReader) first all necessary components of the BFL are declared.
After this, all relevant data structs are declared. Doing this you may start to initialise the BFL stack.
In this example the serial interface of a PC is used. The initialisation of this part is not shown in this
example. The BAL needs only to know about the interface, so the handle is set to the com handle of
the BAL.
Then everything is ready to initialise the RC522. This is done by using dedicated functions of the
operation control component.
Then a timeout value has to be defined and the first command of the activation can be started.
After successful activation there are exapmles shown how to authenticate a Mifare Card and how to
read or write data from the authenticated sector.
At the end an HaltA command is processed, to set the Card into halt state.
/* /////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Philips Semiconductors
//
// (C)PHILIPS Electronics N.V.2004
// All rights are reserved. Reproduction in whole or in part is
// prohibited without the written consent of the copyright owner.
// Philips reserves the right to make changes without notice at any time.
// Philips makes no warranty, expressed, implied or statutory, including but
// not limited to any implied warranty of merchantability or fitness for any
// particular purpose, or that the use will not infringe any third party patent,
// copyright or trademark. Philips must not be liable for any loss or damage
// arising from its use.
/* Common headers */
#include <joinerreg.h>
#include <rclstruct.h>
#include "ExampleUtilsC.h"
/*
* This example shows how to act as Mifare reader
*/
int ActivateMifareReader(int comHandle)
{
/* Declaration of RCL Component Structures (auto), C variant: */
C_BAL bal;
C_RC_REG_CTL rc_reg_ctl;
C_RC_IO rcio;
C_RC_OP_CTL rc_op_ctl;
C_ISO_14443_3A iso14443_3;
C_MIFARE_READER mfrd;
/* Declaration of internal Component Structures: */
#ifdef WIN32
C_JOINER_RS_232_PC_BAL_PARAMS bal_params;
#else
C_JOINER_RS_232_LINUX_BAL_PARAMS bal_params;
#endif
C_JOINER_RS_232_PC_RC_REG_CTL_PARAMS rc_reg_ctl_params;
C_JOINER_RC_IO_PARAMETERS rc_io_params;
C_JOINER_RC_OP_CTL_PARAMETERS rc_op_ctl_params;
C_JOINER_ISO_14443_3_PARAMETERS iso_14443_3_params;
C_MF_RD_INTL_PARAMS mifare_params;
/*
* Declaration of used parameter structures
*/
/* Register control parameters */
RCREGCTL_GETREG_PARAM grp;
RCREGCTL_SETREG_PARAM srp;
RCREGCTL_MODIFY_PARAM mrp;
/* Operation control parameters */
RCOPCTL_ATTRIB_PARAM opp;
/* ISO14443-3 parameters */
ISO14443_3_REQUEST_A_PARAM req_p;
ISO14443_3_ANTICOLLISIONSELECT_PARAM sel_p;
ISO14443_3_HALT_A_PARAM hlt_p;
/* Mifare parameters */
MIFARE_CMD_PARAM mfr_p;
/* Let the BAL know about the used serial Port which is initialiesed outside of this function */
#ifdef WIN32
((C_JOINER_RS_232_PC_BAL_PARAMS*) (bal.mp_Members))->com_handle = (void*) comHandle;
#else
((C_JOINER_RS_232_LINUX_BAL_PARAMS*) (bal.mp_Members))->com_handle = comHandle;
#endif
/* Configure RC522 to act as a Mifare Reader. All register which are set in other modes
* are configured to the right values.
* Remark: The operation control function does not perform a softreset and does not know anything
* about the antanna configuration, so these things have to be handled separately!
*/
opp.group_ordinal = RCO_GROUP_MODE;
opp.attrtype_ordinal = RCO_ATTR_MFRD_A;
opp.param_a = RCO_VAL_RF106K;
opp.param_b = RCO_VAL_RF106K;
status = rc_op_ctl.SetAttrib(&opp);
/* Check status and display error if something went wrong */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR performing Mifare Reader configuration! Status = %04x \n", status);
/* Set the timer to auto mode, 5ms using operation control commands before HF is switched on to
* guarantee Iso14443-3 compliance of Polling procedure
*/
status = SetTimeOut(&rc_op_ctl, 5000);
/*
* After switching on the timer wait until the timer interrupt occures, so that
* the field is on and the 5ms delay have been passed.
*/
grp.address = JREG_COMMIRQ;
do {
status = rc_reg_ctl.GetRegister(&grp);
}
while(!(grp.reg_data & JBIT_TIMERI) && status == RCLSTATUS_SUCCESS);
/* Check status and diplay error if something went wrong */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! GetRegister: Address=%02X, Data=%02X, Status = %04x \n",
grp.address, grp.reg_data, status);
/*
* Reset timer 1 ms using operation control commands (AutoMode and Prescaler are the same)
* set reload value
*/
status = SetTimeOut(&rc_op_ctl, 5000);
/*
* Do activation according to ISO14443A Part3
* Prepare the Request command
*/
buffer[0] = 0;
buffer[1] = 0;
req_p.req_code = ISO14443_3_REQIDL; /* Set Request command code (or Wakeup: ISO14443_3_REQALL) */
req_p.atq = buffer; /* Let Request use the defined return buffer */
status = iso14443_3.RequestA(&req_p); /* Start Request command */
/*
* In normal operation this command returns one of the following three return codes:
* - RCLSTATUS_SUCCESS At least one card has responded
* - RCLSTATUS_COLLISION_ERROR At least two cards have responded
* - RCLSTATUS_IO_TIMEOUT No response at all
*/
if(status == RCLSTATUS_SUCCESS || status == RCLSTATUS_COLLISION_ERROR)
{
/* There was at least one response */
if(status == RCLSTATUS_COLLISION_ERROR)
printf("[W] Multiple Cards detected!! Collission occured during Request!\n");
printf("ATQA = %02x %02x \n", req_p.atq[0],req_p.atq[1]);
} else
/* No response at all */
printf("*** ERROR! RequestA: RequestCode=%02X, ATQA=%02X %02X, Status = %04x \n",
req_p.req_code, req_p.atq[0],req_p.atq[1], status);
/*
* Up to this point the ISO14443-3A protocol has been used
* Now part 3 is finished and one has to choose between the several branches. Here is the
* example how to use the Mifare Standard specific command set of the BFL
*/
status = mfrd.Transaction(&mfr_p);
/* Check return code and display error number if an error occured, else display data */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareWrite: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
printf("Write of block %02X successful, continue operation.\n", mfr_p.addr);
/* Prepare data for Mifare Read again to check what has been written */
mfr_p.cmd = MIFARE_READ;
mfr_p.addr = 0x05;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 0;
status = mfrd.Transaction(&mfr_p);
/* Check return code and display error number if an error occured, else display data */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareRead: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
{
printf("Mifare Read: Block=%02X, Data: ", mfr_p.addr);
for(i=0;i<mfr_p.buffer_length;i++)
printf("%02X",mfr_p.buffer[i]);
printf("\n");
}
/*
* Mifare Value Block operation example
*/
/*
* Prepare data for Mifare Authentication for example of Value block operation.
* The same as in the previous example.
*/
index = 6;
for(i=0;i<4;i++)
buffer[index++] = serial[i];
for(i=0;i<6;i++)
buffer[i] = 0xFF;
mfr_p.cmd = MIFARE_AUTHENT_A;
mfr_p.addr = 0x09;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 10;
status = mfrd.Transaction(&mfr_p);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! Mifare Authentication: Command=%01X, Block=%02X, Status = %04x \n",
mfr_p.cmd, mfr_p.addr, status);
else
printf("Authentication of block %02X successful, continue operation.\n", mfr_p.addr);
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 10000);
/* Init Block 9 as value block with value 100 with Mifare write
* Data in hex: 64 00 00 00 9B FF FF FF 64 00 00 00 09 F6 09 F6 */
mfr_p.cmd = MIFARE_WRITE ;
mfr_p.addr = 0x09;
mfr_p.buffer_length = MIFARE_STD_BLOCK_SIZE;
i=0;
/* init 1st 4 bytes with the specified value */
buffer[i++] = 0x64; // 0x64 == 100
buffer[i++] = 0x00;
buffer[i++] = 0x00;
buffer[i++] = 0x00;
/* 2nd 4 bytes must have bit-inverted value */
for( ; i<8; i++)
buffer[i] = (unsigned char)(~buffer[i-4]);
/* 3rd 4 bytes must have same value as 1st 4 bytes */
for( ; i<12; i++)
buffer[i] = buffer[i-8];
/* 4th 4 byte contain the address, twice plain, twice bit inverted */
buffer[i++] = mfr_p.addr;
buffer[i++] = (unsigned char)(~mfr_p.addr);
buffer[i++] = mfr_p.addr;
buffer[i++] = (unsigned char)(~mfr_p.addr);
/* Prepare data for Mifare Read again to check what has been written */
mfr_p.cmd = MIFARE_READ;
mfr_p.addr = 0x09;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 0;
status = mfrd.Transaction(&mfr_p);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareRead: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
{
printf("Mifare Read: Block=%02X, Data: ", mfr_p.addr);
for(i=0;i<mfr_p.buffer_length;i++)
printf("%02X",mfr_p.buffer[i]);
printf("\n");
}
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 5000);
mfr_p.cmd = MIFARE_TRANSFER;
mfr_p.addr = 0x09;
/* Start Mifare Transfer command */
status = mfrd.Transaction(&mfr_p);
/* Check return code and display error number if an error occured, else display data */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareTransfer: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
printf("Transfer successful, continue operation.\n");
/* Prepare data for Mifare Read again to check what has been written with increment */
mfr_p.cmd = MIFARE_READ;
mfr_p.addr = 0x09;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 0;
/* Start Mifare Read */
status = mfrd.Transaction(&mfr_p);
/* Check return code and display error number if an error occured, else display data */
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareRead: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
{
printf("Mifare Read: Block=%02X, Data: ", mfr_p.addr);
for(i=0;i<mfr_p.buffer_length;i++)
printf("%02X",mfr_p.buffer[i]);
printf("\n");
}
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 5000);
/* Prepare data for Mifare Read again to check what has been written with decrement */
mfr_p.cmd = MIFARE_READ;
mfr_p.addr = 0x09;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 0;
status = mfrd.Transaction(&mfr_p);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareRead: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
{
printf("Mifare Read: Block=%02X, Data: ", mfr_p.addr);
for(i=0;i<mfr_p.buffer_length;i++)
printf("%02X",mfr_p.buffer[i]);
printf("\n");
}
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 5000);
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 10000);
/* Prepare data for Mifare Read again to check what has been written */
mfr_p.cmd = MIFARE_READ;
mfr_p.addr = 0x08;
mfr_p.buffer = buffer;
mfr_p.buffer_length = 0;
status = mfrd.Transaction(&mfr_p);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareRead: Block=%02X, Status = %04x \n", mfr_p.addr, status);
else
{
printf("Mifare Read: Block=%02X, Data: ", mfr_p.addr);
for(i=0;i<mfr_p.buffer_length;i++)
printf("%02X",mfr_p.buffer[i]);
printf("\n");
}
mfr_p.cmd = MIFARE_WRITE4;
mfr_p.addr = 0x07;
mfr_p.buffer_length = MIFARE_UL_PAGE_SIZE;
for(i=0; i < mfr_p.buffer_length; i++)
buffer[i] = (unsigned char)(i + 0x90);
mfr_p.buffer = buffer;
*/
/* Start Mifare Write 4 */
/*
status = mfrd.Transaction(&mfr_p);
if(status != RCLSTATUS_SUCCESS)
printf("*** ERROR! MifareWrite4: Page=%02X, Status = %04x \n", mfr_p.addr, status);
else
printf("Write4 successful, continue operation.\n");
*/
/*
* Do ISO14443-3 HaltA for deactivation of the card
*/
/* Set timeouts */
SetTimeOut(&rc_op_ctl, 1000);
status = iso14443_3.HaltA(&hlt_p);
/* Check return code: If timeout occures, RCLSTATUS_SUCCESSS is returned */
if(status == RCLSTATUS_SUCCESS)
{
printf("Halt probably successful, timeout occured\n");
}
else
{
printf("*** ERROR! HaltA: Status = %04x \n", status);
}
return status;
}