Universal RFID API
Universal RFID API
Manual
Windows is a trademark of Microsoft Corporation.
CryptoRF is a trademark of Atmel Corporation.
This product includes software developed by the OpenSSL Project for use in the OpenSSL
Toolkit (http://www.openssl.org).
This product includes software developed by Lee Thomason and Yves Berquin and
distributed as TinyXML (http://www.sourceforge.net/projects/tinyxml).
This product includes software developed by Todd Fast, Timothy Wall and Wayne
Meissner and distributed as Java Native Access (JNA) (https://github.com/twall/jna).
Copyrights 2011 ProximaRF Technology Corp. All rights reserved
No part of this manual may be copied or distributed, transcribed, stored in a retrieval
system, or translated into any human or computer language, in any form or by any
means, electronic, mechanical, magnetic, manual, or otherwise, without the express
written permission of ProximaRF Technology Corp.
Authors: Jeroen Spreeuwenberg and Alexandre Naverniouk
ProximaRF Technology Corp.
1740 H. Dell Range Blvd., Unit #406
Cheyenne, WY 82009
U.S.A
RFID couplers (also called RFID interrogators, RFID readers or RFID scanners) are
electronic devices which can read/write information from/to RFID tags.
Universal RFID API (Application Program Interface) is a set of functions which helps
programmers to interface with our RFID couplers. The Universal RFID API is system and
language agnostic. It is built on a simple, clear, XML based protocol.
This document describes the common structure of the Universal RFID API, its low level
core API and the available XML requests.
Universal RFID API structure
The Universal RFID API has two levels. First, the so called core API. The core API is
written in C++ and it is responsible for the major functionality of the API.
Above this core level there are different platform specific modules, which help to access
the core functions from different platforms.
Also provided is a Java module. It provides Java developers with the same functions as
the Microsoft .NET module.
The core API can also be accessed directly. It is implemented as a DLL and can be called
from any program that can load the DLL into memory and call its functions.
RFID_Core.dll can be called directly from C/C++ programs. RFID_Core.h can be found in
the Universal RFID APIs C++ folder.
s_create
Function s_create() creates a stream which can be used for RFID request.
Syntax:
int s_create();
Defined:
RFID_Core.h
Returns:
Handle of the stream
Note:
The number of open streams are limited, so do not forget to close and dispose all the
streams when finished.
s_close
Function s_close() closes the stream and releases all the memory used.
Syntax:
Defined:
RFID_Core.h
Parameters:
handler handle of the opened stream
Returns:
Byte from the stream or -1 if there is no more bytes to r
s_putch
Function s_putch() writes a byte into the stream.
Syntax:
Defined:
RFID_Core.h
Parameters:
handler handle of the opened stream
ch byte to write
void s_write( int handler, char const *data, unsigned int len );
Defined:
RFID_Core.h
Parameters:
handler handle of the opened stream
data pointer to the bytes
len number of bytes to write
s_write_string
Function s_write_string() writes an ASCII 0-terminated string into the stream.
Syntax:
Defined:
RFID_Core.h
Parameters:
handler handle of the opened stream
str ASCII 0-terminated string
s_getlength
Function s_getlength() returns the number of bytes in the stream.
Syntax:
Defined:
RFID_Core.h
Parameters:
handler handle of the opened stream
pos position from the beginning of the stream
Returns:
New position in the stream.
s_tellp
Function s_tellp() returns current position in the stream.
Syntax:
Defined:
RFID_Core.h
Parameters:
handler handle of the opened stream
Returns:
Current position in the stream.
Defined:
RFID_Core.h
Parameters:
handler handle of the opened stream
Returns:
Pointer to the internal buffer of the stream. If it is needed the fuction first adds 0 byte
into the end of the stream.
Comments:
Note to be cautious and not to overrun the buffer. You can get the length of the stream
by calling s_getlength().
RFID
Function RFID() is the main function of the core API. It processes the XML request and
returns the result of the operation. All the XML RFID requests are described later in this
document.
Syntax:
Defined:
RFID_Core.h
Parameters:
handler handle of the stream with the XML request.
Returns:
Handle of the stream with the XML response.
using ProximaRF.RFID;
Call
Call is the main function of RFID_NET. The method takes an XmlDocument containing
the XML request in and returns an XmlDocument with the XML response.
In addition to the Call function, RFID_NET also has some auxiliary functions which help
process the XML result
GetError
GetError function returns the error codes value from the XML response
EncodeHex
EncodeHex function encodes a byte array into a hexadecimal string.
DecodeHex
DecodeHex function decodes a byte array from a hexadecimal string.
These helper classes are available from the RFID_NET module. You can also add the
helper classes source files directly into your C# .NET project. Each helper class allows
you to create an object in your source code that is specific to an RFID protocol and/or
Proxima RF (sensor) product.
Each helper class provides you with functions that can be called directly from your
source code. It hides the Universal RFID APIs XML response and request structure from
your code allowing for an even faster implementation. The available functions are
explained in great detail using commentary in the available source code. Information is
also made available while coding through the Microsoft Visual Studio IntelliSense
interface.
Below is an example of how to use the SensorTag Helper class to read the current
temperature from a compatible SensorTag passive RFID temperature tag:
using ProximaRF.RFID;
import ProximaRF.RFID;
Call
Call is the main function of RFID_Java. The method takes a String containing the XML
request in and returns a String with the XML response.
In addition to the Call function, RFID_Java also has some auxiliary functions which help
process the XML result
GetError
GetError function returns the error codes value from the XML response
EncodeHex
EncodeHex function encodes a byte array into a hexadecimal string.
DecodeHex
DecodeHex function decodes a byte array from a hexadecimal string.
<RFID>
<command>{Command Name}</command>
{additional parameters}
</RFID>
The XML response also has the 'RFID' root element. In addition every response has an
'error-code' parameter (see Appendix). If the 'error-code' parameter is not 0, an 'error-
text' parameter is also provided. It contains the matching textual error message.
<RFID>
<error-code>
{0 if no errors, or some numeric error code}
</error-code>
<error-text>
{text commentary to the error}
</error-text>
{additional data tags}
</RFID>
Initialize request
The Initialize request should be send to the API before any other requests. It opens
communication with the RFID coupler and configures it according to the specified
parameters.
Request:
<RFID>
<command>Initialize</command>*
<device>{AP1/AP2/AV-X/PRFD/PRFM}</device>*
<protocol>{ISO15693/CryptoRF (default is ISO15693)}</protocol>
<subcarrier>{single/dual (default is dual)}</subcarrier>
<modulation>{10%/100% (default is 10%)}</modulation>
<port>{COM1/COM2/COM3/...}</port>*
<baud>{9200/57600/ (default is 57600)}</baud>
<parity>{0/1 (default is 0)}</parity>
<stop-bits>{0/1/2 (default is 0)}</stop-bits>
<flow-control>{none/hardware (default is none)}</flow-control>
<mode>{text/binary (default is text)}</mode>
<field>{auto/manual (default is auto, manual required for MLX90129)}</field>
<connector>{scannerport/xmod (default is scannerport)}</connector>
<manufacturer-code>{hexadecimal manufacturer byte to be added into
MLX90129 commands (default is 1F)}</manufacturer-code>
<memory-addressing-bits>{8/16/24 (default is 8)}
</memory-addressing-bits>
</RFID>
<RFID>
<version>{API version}</version>
<error-code>0</error-code>
</RFID>
Notes:
Windows CE/Mobile requires port names to end with ':' (COM3:).
Values of the stop-bits parameter have the following meaning:
0 1 stop bit
1 1.5 stop bits
2 2 stop bits
For more information on 'protocol', 'subcarrier' and 'modulation' refer to the ISO15693
protocol specification available from ISO/IEC and/or the CryptoRF datasheet available
from Atmel.
GetAPIInfo requests
The GetAPIInfo request returns the version number of the currently used API.
Request:
<RFID>
<command>GetAPIInfo</command>*
</RFID>
<RFID>
<version>{API version}</version>
<error-code>0</error-code>
</RFID>
Sleep request
The Sleep request will put the RFID coupler into sleep mode and turn off the RF field if
the field parameter was set to manual in the Initialize request.
Request:
<RFID>
<command>Sleep</command>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
</RFID>
WakeUp request
The WakeUp request will put the RFID coupler into operating mode and turn on the RF
field if the field parameter was set to manual in the Initialize request.
Request:
<RFID>
<command>WakeUp</command>*
</RFID>
<RFID>
<error-code>0</error-code>
</RFID>
Close request
The Close request will close the connection with the RFID coupler.
Request:
<RFID>
<command>Close</command>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
</RFID>
For more information about the ISO15693 protocol please refer to the ISO15693
specification available from ISO/IEC.
GetTagInfo request
The GetTagInfo request will make the RFID coupler communicate with a compliant RFID
tag and will return that tags information.
Request:
<RFID>
<command>GetTagInfo</command>*
</RFID>
Response:
<RFID>
<tag-type>{Type of the Tag}</tag-type>
<tag-id>{Unique Tag ID (UID)}</tag-id>
<error-code>0</error-code>
</RFID>
<RFID>
<command>ReadTag</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<read-from>{Number (address) of the first byte to read}</read-from>*
<total-bytes> {Total number (length) of bytes to read}</total-bytes>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
<data>{Data in hexadecimal format}</data>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
<RFID>
<command>WriteTag</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<write-from> {Number (address) of the first byte to write}</write-from>*
<total-bytes> {Total number (length) of bytes to write}</total-bytes>*
<data>{Data in hexadecimal form}</data>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
For more information about CryptoRF please refer to the CryptoRF datasheet
available from Atmel.
GetTagInfo request
The GetTagInfo request will make the RFID coupler communicate with a compliant RFID
tag and will return that tags information.
Request:
<RFID>
<command>GetTagInfo</command>*
</RFID>
Response:
<RFID>
<tag-type>{Type of the Tag}</tag-type>
<tag-id>{Unique Tag ID (UID)}</tag-id>
<error-code>0</error-code>
</RFID>
<RFID>
<command>ReadTag</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<read-from>{Number (address) of the first byte to read}</read-from>*
<total-bytes> {Total number (length) of bytes to read}</total-bytes>*
<user-zone>{User zone to read from}</user-zone>*
<password>{Read password associated with specified user zone}</password>
<password-index>{Index associated with specified password}
</password-index>
<authentication-key>{Authentication key associated with specified user zone}
</authentication-key>
<authentication-key-index>{Index associated with specified authentication key}
</authentication-key-index>
<encryption-key>{Encryption key associated with specified user zone}
</encryption-key>
</RFID>
Response:
<RFID>
<error-code>0</error-code>
<data>{Data in hexadecimal format}</data>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
<RFID>
<command>WriteTag</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<write-from> {Number (address) of the first byte to write}</write-from>*
<total-bytes> {Total number (length) of bytes to write}</total-bytes>*
<data>{Data in hexadecimal form}</data>*
<user-zone>{User zone to read from}</user-zone>*
<password>{Write password associated with specified user zone}</password>
<password-index>{Index associated with specified password}
</password-index>
<authentication-key>{Authentication key associated with specified user zone}
</authentication-key>
<authentication-key-index>{Index associated with specified authentication key}
</authentication-key-index>
<encryption-key>{Encryption key associated with specified user zone}
</encryption-key>
</RFID>
Response:
<RFID>
<error-code>0</error-code>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
For more information about the MLX90129 please refer to the MLX90129 datasheet
available from Melexis.
GetTagInfo request
The GetTagInfo request will make the RFID coupler communicate with a compliant RFID
tag and will return that tags information.
Request:
<RFID>
<command>GetTagInfo</command>*
</RFID>
Response:
<RFID>
<tag-type>{Type of the Tag}</tag-type>
<tag-id>{Unique Tag ID (UID)}</tag-id>
<error-code>0</error-code>
</RFID>
<RFID>
<command>ReadRegisterFile</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<read-from>{Number (address) of the first byte to read}</read-from>*
<total-bytes> {Total number (length) of bytes to read}</total-bytes>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
<data>{Data in hexadecimal format}</data>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
<RFID>
<command>WriteRegisterFile</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<write-from> {Number (address) of the first byte to write}</write-from>*
<total-bytes> {Total number (length) of bytes to write}</total-bytes>*
<data>{Data in hexadecimal form}</data>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
UpdateRegisterFile request
The UpdateRegisterFile request will update the register file of a MLX90129 based tag.
Request:
<RFID>
<command>UpdateRegisterFile</command>*
</RFID>
<RFID>
<error-code>0</error-code>
</RFID>
ReadInternalMemory request
The ReadInternalMemory request will read information, as specified, from a MLX90129
based tags internal memory (EEPROM).
Request:
<RFID>
<command>ReadInternalMemory</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<read-from>{Number (address) of the first byte to read}</read-from>*
<total-bytes> {Total number (length) of bytes to read}</total-bytes>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
<data>{Data in hexadecimal format}</data>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
<RFID>
<command>WriteInternalMemory</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<write-from> {Number (address) of the first byte to write}</write-from>*
<total-bytes> {Total number (length) of bytes to write}</total-bytes>*
<data>{Data in hexadecimal form}</data>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
<RFID>
<command>ReadExternalMemory</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<read-from>{Number (address) of the first byte to read}</read-from>*
<total-bytes> {Total number (length) of bytes to read}</total-bytes>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
<data>{Data in hexadecimal format}</data>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
<RFID>
<command>WriteExternalMemory</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<write-from> {Number (address) of the first byte to write}</write-from>*
<total-bytes> {Total number (length) of bytes to write}</total-bytes>*
<data>{Data in hexadecimal form}</data>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
<RFID>
<command>ReadInternalDevice</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<read-from>{Number (address) of the first byte to read}</read-from>*
<total-bytes> {Total number (length) of bytes to read}</total-bytes>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
<data>{Data in hexadecimal format}</data>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
<RFID>
<command>WriteInternalDevice</command>*
<tag-type>{Tag type}</tag-type>
<tag-id>{Tag ID}</tag-id>
<write-from> {Number (address) of the first byte to write}</write-from>*
<total-bytes> {Total number (length) of bytes to write}</total-bytes>*
<data>{Data in hexadecimal form}</data>*
</RFID>
Response:
<RFID>
<error-code>0</error-code>
</RFID>
Note:
When the 'tag-type' and 'tag-id' parameters are not present the RFID coupler will
communicate with the RFID tag in the unaddressed mode.
using ProximaRF.RFID;
// Send the Initilaize request to the API and parse the XML repsonse
response = RFID.Call(request);
if (RFID.GetError(response) != 0)
throw new Exception(RFID.GetParameter(response, "error-text"));
// Scan for an ISO15693 compliant tag and get its information (UID)
// Prepare the XML GetTagInfo request
request = new XmlDocument();
request.LoadXml("<RFID>
<command>GetTagInfo</command>
</RFID>");
if (RFID.GetError(response) != 0)
throw new Exception(RFID.GetParameter(response, "error-text"));
// Send the ReadTag request to the API and parse the XML repsonse
response = RFID.Call(request);
if (RFID.GetError(response) != 0)
throw new Exception(RFID.GetParameter(response, "error-text"));
// Send the Close request to the API and parse the XML repsonse
response = RFID.Call(request);
if (RFID.GetError(response) != 0)
throw new Exception(RFID.GetParameter(response, "error-text"));
}
using ProximaRF.RFID;
// Send the Initilaize request to the API and parse the XML repsonse
response = RFID.Call(request);
if (RFID.GetError(response) != 0)
throw new Exception(RFID.GetParameter(response, "error-text"));
// Send the WriteTag request to the API and parse the XML repsonse
response = RFID.Call(request);
// Send the Close request to the API and parse the XML repsonse
response = RFID.Call(request);
if (RFID.GetError(response) != 0)
throw new Exception(RFID.GetParameter(response, "error-text"));
}
using ProximaRF.RFID;
// Send the Initilaize request to the API and parse the XML repsonse
response = RFID.Call(request);
if (RFID.GetError(response) != 0)
throw new Exception(RFID.GetParameter(response, "error-text"));
// Read internal device address 0x06 from an MLX90129 based tag (sensor 0)
// Prepare the XML ReadInternalDevice request
request = new XmlDocument();
request.LoadXml("<RFID>
<command>ReadInternalDevice</command>
<read-from>12</read-from>
<total-bytes>2</total-bytes>
</RFID>");
// Read internal device address 0x02 from an MLX90129 based tag (sensor buffer)
// Prepare the XML ReadInternalDevice request
request = new XmlDocument();
request.LoadXml("<RFID>
<command>ReadInternalDevice</command>
<read-from>4</read-from>
<total-bytes>2</total-bytes>
</RFID>");
// Send the ReadInternalDevice request to the API and parse the XML repsonse
response = RFID.Call(request);
if (RFID.GetError(response) != 0)
throw new Exception(RFID.GetParameter(response, "error-text"));
// Parse the sensor's ADC value (put your own parsing code here)
MessageBox.Show(RFID.EncodeHex(data));
using ProximaRF.RFID;
using ProximaRF.RFID;
using ProximaRF.RFID;
// Check the field strength (only accept sensor readings if RF field is strong enough)
if (SensorTagh.CheckFieldStrength(tagtype, tagid, 2))
{
// Read the validated temperature in celcius
tempC = SensorTagh.ReadSensor(0, tagtype, tagid);
tempF = (tempC * 9 / 5) + 32;
Now click on the Call button, and the program will call the Universal RFID API using the
selected XML request. After the call has been completed you will see the APIs XML
response in the bottom text field.