C H A P T E R  3

Using RFID Device Client APIs

This chapter describes how to use the Java APIs for reader and printer clients.

Each Execution Agent provides one or more reader services. A reader service is a specialized web service that communicates with the RFID device, processes the information as directed by the RFID Event Manager configuration object, and communicates with the RFID Information Server or third-party Enterprise Resource Planning (ERP) systems. Configuration objects are defined for each specific reader using the RFID Configuration Manager. See the Sun Java System RFID Software 3.0 Administration Guide if you are not familiar with the concept of a configuration object and how they are defined.

In the RFID Event Manager, the reader service performs the work of gathering RFID tag events. The reader service communicates the state of its components to the management service (another specialized web service). The communication from the reader service to the management service enables the RFID Management Console to monitor the components.

Previous releases of the RFID Software required developers to be familiar with Jini programming in order to discover the reader service in the Jini lookup server and to invoke the service's device access methods.

A set of reader and printer client APIs has been implemented to hide some of the complexity of working directly with Jini services.

This chapter includes the following topics:


Implementation of the ReaderClient API

The implementation of the ReaderClient API is contained in the com.sun.autoid.util.ReaderClient class and is packaged in the sun-rfid-common.jar JAR file.

This section covers the following topics:

Reader Client Constructor Parameters

There are many ways of instantiating a ReaderClient constructor. The various parameters for the ReaderClient constructors are described in the following sections:

Reader Client Groups Parameter

During installation of the RFID Event Manager Control Station, you are prompted to enter a group name. All readers configured for this Control Station are associated by that group name. If a second Control Station is started, a unique group name for this Control Station must be assigned. All readers in this Control Station are then associated by this new group name. The ReaderClient class uses this group name to help narrow the search for a given reader. If no group name is specified, then all groups are searched.

Many of the ReaderClient constructors take a String[] groups argument. This argument is a String array of group names. If all groups are to be searched, then the argument is null. You can use the ReaderClient method String[] getGroups(String groupStr) to create this array of group names. The getGroups () method takes a String of group names and returns a String array of group names. Each group name is separated from the next group name by a space, a tab or a comma, with a special case for all or none.

Reader Client Locators Parameter

By default, a reader client can only find those readers that are running on RFID Event Manager Execution Agents and Control Stations within the same subnet. You can extend the search for readers outside this subnet by adding locators. A locator is defined in terms of a URL format. For example, jini://hostname:port.

The variable, hostname, is the host name or IP address of a machine that is running the RFID Event Manager Control Station that manages the reader services that you want to add to the reader search list.

The, variable, port, is the Jini lookup server port number. This port number is optional when defining a new locator, unless you customized the port number during the installation of the RFID Event Manager. If you add a Jini location and the port number is not specified, the default Jini lookup server port, 4160, is used. If you customized the Jini lookup server port during installation, you must specify the same port number when you add a locator to this Jini lookup server. The port number must match the one used during installation.

Many of the ReaderClient constructors take a LookupLocator[] locators argument. This should be a LookupLocator array of locator objects or null if only the local subnet is to be searched. You might also use the ReaderClient method LookupLocator[] getLocators(String locatorStr) to create this array of locator objects. The getLocators () method takes a String of locator values in the URL format Each locator is separated from the next location by a space, a tab or a comma, and returns an array of LookupLocator objects.

Reader Client readerName Parameter

All ReaderClient constructors require you to supply a reader name as an input. This reader name is the name of the specific device as configured in the RFID Configuration Manager.

For example, you might specify PMLReader or testIntermecReader as the readerName parameter to the ReaderClient constructor to reach one of the two devices shown in the following screen capture. To create your own specific readers, consult the Sun Java System RFID Software 3.0 Administration Guide. The testIntermecReader shown in the screen shot is for demonstration purposes and does not represent a real reader.


Screen capture showing RFID Configuration Manager with two readers, PMLReader and testIntermecReader defined.

Reader Client eventID Parameter

An eventID is a unique number used by the RFID Software to identify remote event producers (REProducer) for tag events. Client applications use this identifier to connect to a specific REProducer component. In RFID Software 3.0, each reader automatically creates a REProducer component using a randomly generated unique number.



Note - In RFID Software 2.0, you had to use a separate REProducer component in the reader's processing chain specifically for this purpose and then use the eventID to locate the REProducer. It is no longer necessary to include a REProducer connector for this purpose.



Generally, you should locate the reader's internal REProducer by using the reader's physical name. If you want to control the assignment of the eventID number, you define a Handle property in the reader's configuration.

Some of the ReaderClient constructors take an eventID parameter. If an eventID is specified, then the reader client connects to the default REProducer and matches a reader with this eventID.

The eventID may be null. If the eventID is null, then the reader's event producer is found by using the reader's physical name. The reader physical name is the name assigned to the reader when you define the physical device using the RFID Configuration Manager. See "To Define the RFID System Physical Devices" in the Sun Java System RFID Software 3.0 Administration Guide.

When an eventID is specified, the reader adapter configuration must contain a Handle property. To establish a connection to the reader's event producer, the value of the Handle property must match the reader client eventID parameter.

You use the RFID Configuration Manager to add a Handle property to a reader adapter. The reader adapter configuration is referred to as a device in the RFID Configuration Manager. Handle is not a default property for a device, so you must add the Handle property using the RFID Configuration Manager. See To Add a Handle Configuration Property to a Device.


procedure icon  To Add a Handle Configuration Property to a Device

Prerequisite - This procedure assumes that you are familiar with how to use the RFID Configuration Manager. See the Sun Java System RFID Software 3.0 Administration Guide for more information on how to define and configure devices in the RFID network.

1. If you have not already done so, start the RFID Configuration Manager.

2. From the RFID Configuration Manager menu, choose Devices right arrow Edit.

A dialog listing the available devices appears.


Screen capture of the RFID Configuration Manager Edit Devices dialog box. Buttons are Ok and Cancel.

3. Select the specific reader and click Ok.

For the purposes of this example, the testIntermecReader was selected. An edit dialog box for the device appears as shown in the following screen capture.


Screen capture showing reader properties modification dialog box.

4. Select any configuration property name field.

5. Right-click and choose Add Property from the context menu.

A blank row appears enabling you to add the Name and Value for the new property.


Screen capture showing the Edit Device configuration properties dialog box with a new property. Name and Value fields for the new property are blank. Buttons are Ok and Cancel.

6. In the new configuration property Name field, type Handle.

7. In the Value field, type 55123 and click Ok.

The new configuration property is added to the device. The following screen capture shows the newly added configuration property of Handle with a value of 55123 added to the testIntermecReader.


Screen capture of Device Edit dialog box showing the new Handle property and its value.

8. Choose File right arrow Save to save your change.

Using the configuration that is shown in this example procedure, use the Handle value of 55123 to create a ReaderClient as shown in the following code example.


CODE EXAMPLE 3-1 Creating a ReaderClient

public class MyReaderClient implements EMSEventListener {

public static void mainString[] args) {

System.setSecurityManager(new RMISecurityManager());

long eventID = 55123;

ReaderClient = new ReaderClient("testIntermecReader", eventId, this);

}

...

}

 


Reader Client logical Parameter

One of the ReaderClient constructors enables you to specify the String logical. This String refers to a group of logical readers that have been defined during the RFID Event Manager configuration. For example, a single dock door may have several readers positioned strategically around the door to enable the best read possible as pallets pass through the door. It might be useful to group these readers into a logical group that can be tracked as a single unit. The logical parameter enables you to discover a reader when the reader is part of a specific logical group.

To use the logical parameter, you must define a logical group using the RFID Configuration Manager. For example, you might create a logical group named, Dock Door 1 that contains two readers, DockDoorEast and DockDoorWest. This enables you to refer to both of these readers using the logical name of Dock Door 1. Use the RFID Configuration Manager to configure two readers with a logicalReaders property of Dock Door 1.

A ThingMagic Mercury4 reader named DockDoorEast that is configured with a logicalReaders property, Dock Door 1, appears in the following screen capture from the RFID Configuration Manager. You would configure the reader at DockDoorWest in the same way.


Screen capture showing the Edit Device configuration dialog box with a logicalReaders property.



Note - When you configure a device to be part of a logicalReaders group, if the logicalReaders property does not already appear in the Configuration Properties list, you can add it to the device configuration. Use a procedure similar to that described for adding the Handle property. See To Add a Handle Configuration Property to a Device.



EMSEventListener

The ReaderClient API also enables you to specify an EMSListener to receive reader events. If specified, this listener is registered with the default reader event producer and receives events using the postEvent() method. The EMSEventListener can be null.

ReaderClient API Reference

All of the public ReaderClient APIs are listed in the following table.


TABLE 3-1 ReaderClient Interfaces

Constructors and Methods

Description

ReaderClient(String readerName)

  • Creates a new ReaderClient instance matching on the readerName in ALL groups.
  • The default event producer is used.
  • No remote listener is registered. If one is used, it must be manually registered using the addEMSEventListener() method.

ReaderClient(String readerName, String[]groups)

  • Creates a new ReaderClient instance matching on the reader name in groups specified by the groups parameter. See getGroups () method for details.
  • The default Event Producer is used.
  • No remote listener is registered. If one is used, it must be manually registered using the addEMSEventListener() method.

ReaderClient(String readerName, String[]groups, Locator[] locators)

  • Creates a new ReaderClient instance matching on the Reader Name in groups specified by the groups parameter. See getGroups () method for details.
  • The local subnet is searched in addition to hosts specified by the locators parameter. See getLocators() method for details.
  • The default Event Producer is used.
  • No Remote Listener is registered. If one is used, it must be manually registered using the addEMSEventListener() method.

ReaderClient(String readerName, EMSEventListener listener)

  • Creates a new ReaderClient instance matching on the Reader Name in ALL groups.
  • The default Event Producer is used
  • The specified listener is registered to the default reader event producer.

ReaderClient(String readerName, long eventID, EMSEventListener listener)

  • Creates a new ReaderClient instance matching on the Reader Name in ALL groups.
  • The specified listener is registered to the default reader event producer for a reader adapter that has explicitly set its Handle id and must match the eventID parameter.

ReaderClient(String readerName, long eventID, String[] groups, EMSEventListener listener)

  • Creates a new ReaderClient instance matching on the Reader Name in groups specified by the groups parameter. See getGroups () method for details.
  • The default Event Producer is used.
  • The specified listener is registered to the default reader event producer for a reader adapter that has explicitly set its Handle id and must match the eventID parameter.

ReaderClient(String readerName, String[]groups, EMSEventListener listener)

  • Creates a new ReaderClient instance matching on the Reader Name in groups specified by the groups parameter. See getGroups () method for details.
  • The default Event Producer is used.
  • The specified listener is registered to the default reader event produce to receive reader events.

ReaderClient(String readerName, String[] groups, Locator[] locators, EMSEventListener listener)

  • Creates a new ReaderClient instance matching on the Reader Name in groups specified by the groups parameter (see getGroups () method for details.
  • The local subnet is searched as well as any additional hosts as specified by the locators parameter. See getLocators() method for details.
  • The default Event Producer is used.
  • The specified listener is registered to the default reader event producer to receive reader events.

ReaderClient(String readerName, long eventID, String[] groups, Locator[] locators, EMSEventListener listener)

  • Creates a new ReaderClient instance matching on the Reader Name in groups specified by the groups parameter (see getGroups () method for details.
  • The local subnet is searched in addition to hosts specified by the locators parameter. See getLocators() method for details.
  • The specified listener is registered to the default reader event producer for a reader adapter that has explicitly set its Handle id and must match the eventID parameter.

ReaderClient(String readerName, long eventID, String logical, String[] groups, Locator[] locators, EMSEventListener listener)

  • Creates a new ReaderClient instance matching on the Reader Name in groups specified by the groups parameter. See getGroups () method for details.
  • The local subnet is searched in addition to hosts specified by the locators parameter. See getLocators() method for details.
  • The specified listener is registered to the default reader event producer for a reader adapter that has explicitly set its Handle id and must match the eventID parameter.
  • See Reader Client logical Parameter for details of the logical parameter.

terminate

Terminates discovery of the reader.

checkReaderStatus

Returns true if the reader has been discovered and is connected to its device, else returns false.

getLastList

Gets the last tag list, the tag list is not cleared. A subsequent call to getLastList returns the same list, unless the Remote Event Producer has caused the list to be updated.

takeLastList

Takes the last tag list and clears it afterwards. A subsequent call to getLastList or takeLastList does not return the same list. The subsequent call returns a new list if it has been updated by the Remote Event Producer, or return null, if no update has taken place.

takeLastList (msecs)

Takes the last tag list and clears it afterwards. A subsequent call to getLastList or takeLastList does not return the same list. The subsequent call returns a new list if the last has been updated by the Remote Event Producer, or returns null, if no update has taken place.

This method waits for a period of time for the list to be updated if the list is empty when the call is first made.

getReader

Get the reader interface for this reader. Might return null if the reader has not yet been discovered.

getReader (msecs)

Get the reader interface for this reader. Might return null if the reader has not yet been discovered by the specified wait time.

addEMSEventListener

Add an EMSEventListener to the Remote Event Producer to be notified of reader events.

removeEMSEventListener

Remove an EMSEventListener from the Remote Event Producer canceling notification of reader events


Building a Sample Reader Client Program

A sample reader client program is included in the Sun Java System RFID Software Toolkit. After unzipping the RfidToolkit.zip file into a directory of your choice, toolkit-dir, you can find SampleTagReaderClient.java in the following directory:
toolkit-dir/samples/readerAccess/standAlone.

Before running SampleTagReaderClient, confirm the following prerequisites:


procedure icon  To Set Up the Sample Reader Client Environment

1. Change to the directory containing the reader client sample program.

For example, on a Solaris system where toolkit-dir represents the directory where you downloaded and unzipped the RFID Software Toolkit zip file.


cd toolkit-dir/samples/readerAccess/standAlone

2. Verify that the build.properties file is correct for your installation.

You might need to modify the rfid.home property to point to your specific RFID Event Manager installation.

3. Verify that the build.xml file target sampletagreader contains the correct jvmarg parameter values for your environment as follows.


procedure icon  To Run the Sample Reader Client Program

1. Change to the directory containing the reader client sample program.

For example, on a Solaris system where toolkit-dir represents the directory where you downloaded and unzipped the RFID Software Toolkit zip file.


cd toolkit-dir/samples/readerAccess/standAlone

2. Run the reader client using the ant sampletagreader target.


> ant sampletagreader

3. Run the writer client using the ant sampletagwriter target.


> ant sampletagwriter

Explaining the Sample Reader Client

To create a reader client, you first must set the system security manager and a security policy. This is necessary because you use Jini network technology to discover the reader using the ReaderClient APIs. This step is shown in the following code example.


CODE EXAMPLE 3-2 Setting an RMI Security Manager and the Security Policy

// You must first create an RMI Security manager

System.setSecurityManager(new RMISecurityManager());

// Must also set the security policy

if(System.getProperty("java.security.policy") == null)

System.setProperty("java.security.policy", "./policy.all");

 


Set the codebase property so that the ReaderClient can register a notification call back with the Jini lookup service as follows:


CODE EXAMPLE 3-3 Setting the codebase Property for the Jini Lookup Service

// Must set code base so that the ReaderClient can register a

// notification call back with the Jini Lookup Service

if(System.getProperty("java.rmi.server.codebase") == null)

System.setProperty("java.rmi.server.codebase",

"http://localhost:52493/sdm-dl.jar");

 


Then use one of the many ReaderClient constructors to find the reader.

When you install the RFID Event Manager, you supply a Jini group name. By default, this name is AutoID-hostname. The default RFID Event Manager installation also configures the PMLReader adapter. The PML simulator software simulates tags being sent to the PMLReader adapter. To start the PML simulator software, run the pmlreader script.The script can be found in the rfid-install-dir/bin directory. See the Sun Java System RFID Software 3.0 Administration Guide for more details. Using the default installation configuration and a host name of myHost, the following code example shows how to create a ReaderClient that discovers the PMLReader.


CODE EXAMPLE 3-4 Finding the PMLReader Reader in the AutoID-myHost Group

String readerName = "PMLReader";

String groupStr = "AutoID-myHost";

String locatorStr = null;

ReaderClient readerClient = null;

try {

readerClient = new ReaderClient(readerName,

ReaderClient.getGroups(groupStr),

ReaderClient.getLocators(locatorStr));

// Now get the actual reader implementation

Reader reader = client.getReader(3*1000);

}

}
 

After creating the ReaderClient object, you might use it to get the actual reader interface. The reader interface can be used to access and control the reader.

For example, the following code samples illustrate how to get a list of tags from the reader and how to check the status of a reader.


CODE EXAMPLE 3-5 Printing a List of Tags From the PMLReader Service

// Get tag list from the reader object obtained above using the

// client.getReader() method.

java.util.Collection c = reader.getTagList(readerName, 500);

if (c != null){

Iterator i = c.iterator();

while (i.hasNext()) {

Event event = (Event)i.next();

if (event instanceof IdentifierListEvent) {

IdentifierListEvent eventList = (IdentifierListEvent) event;

System.out.println("The following tags were read from the reader: "

+ eventList.getSource());

Iterator j = eventList.getTagList().iterator();

while (j.hasNext()) {

Identifier epc = (Identifier)j.next();

System.out.println("tag= " + epc.getURI());

}

    }
}
 


Implementation of the PrinterClient API

The implementation of the PrinterClient API is contained in the com.sun.autoid.util.PrinterClient class and is packaged in the sun-rfid-common.jar JAR file.

The PrinterClient.java class extends the ReaderClient.java class and offers additional methods for printing tags. A printer client can be used to find printers using the printer adapter name in the same manner that reader clients find readers using the ReaderClient APIs.

This section covers the following topics:

PrinterClient API Reference

All of the public PrinterClient APIs are listed in the following table.


TABLE 3-2 PrinterClient Interfaces

Constructors and Methods

Description

PrinterClient(String printerName)

Creates a new instance of PrinterClient matching on the printer name in ALL groups.

PrinterClient(String printerName, String[] groups)

Creates a new instance of PrinterClient matching on the printer name in groups specified by the groups parameter.

PrinterClient(String printerName, String[] groups, LookupLocator[] locators)

Creates a new instance of PrinterClient matching on the printer name in groups specified by the groups parameter.

The local subnet is searched as well as any additional hosts that are specified by the locators parameter.

printTag(Identifier id, Properties properties)

Programs the single tag in the printer field of action and prints a label.

The id is the Identifier that is written to the tag.

The properties are applied to a template.

printTag(Identifier id, String printStream)

Programs the single tag in the printer field of action and prints a label.

The id is the Identifier that is written to the tag.

printStream is a String that is sent directly, unchanged, as a print command for this printer.


Building a Sample Printer Client

A sample printer client program is included in the Sun Java System RFID Software Toolkit. After unzipping the RfidToolkit.zip file into a directory of you choice, toolkit-dir, you can find SamplePrinterClient.java in the following directory:
toolkit-dir/samples/readerAccess/standAlone.

Before running SamplePrinterClient, confirm the following prerequisites:


procedure icon  To Set Up the Sample Printer Client Environment

1. Change to the directory containing the printer client sample program.

For example, on a Solaris system where toolkit-dir represents the directory where you downloaded and unzipped the RFID Software Toolkit zip file.


cd toolkit-dir/samples/readerAccess/standAlone

2. Verify that the build.properties file is correct for your installation.

You might need to modify the rfid.home property to point to your specific RFID Event Manager installation.

3. Verify that the build.xml file target sampleprinterclient contains the correct jvmarg parameter values for your environment as follows.

arg - Specifies the identifier to print on the tag. Replace the arg value with the identifier that you want printed on the tag. The default value looks similar to the following:


<arg value="urn:epc:id:gid:10.1002.37">


procedure icon  To Run the Sample Printer Client Program

1. Change to the directory containing the printer client sample program.

For example, on a Solaris system where toolkit-dir represents the directory where you downloaded and unzipped the RFID Software Toolkit zip file.


cd toolkit-dir/samples/readerAccess/standAlone

2. Run the printer client using the ant samplegprinterclient target.


> ant sampleprinterclient

Explaining the Sample Printer Client

Configure a printer device using the RFID Configuration Manager. This example prints to a Zebra Technologies printer with the device name ZebraPrinter. See Sun Java System RFID Software 3.0 Administration Guide for procedures to define the physical printer device for the RFID Event Manager.

The default build.xml file specifies the readerName variable as ZebraPrinter. If you configure a different printer adapter, you need to modify this variable in the sampleprinterclient target. Modify the tag identifier that you wish to print by modifying the arg value parameter in the sampleprinterclient target of build.xml as described in Step 3 of the procedure To Set Up the Sample Printer Client Environment.

The first step in creating a printer client is to set the system security manager. This is necessary because the printer client uses Jini network technology to discover the printer.

See Setting an RMI Security Manager and the Security Policy.

Use one of the three PrinterClient constructors to find the printer.


CODE EXAMPLE 3-6 Finding the ZebraPrinter Printer Instance

String printerName = System.getProperty("com.sun.autoid.ReaderName",

"ZebraPrinter");

try {

PrinterClient client = new PrinterClient(printerName);

// Wait while looking for the reader

System.out.println("Wait while looking for the " + printerName

+ " reader ...");

Thread.sleep(3*1000);

} catch (Exception ex){

ex.printStackTrace();

}
 

After creating the PrinterClient object, you can use it to print tags. The following code example shows how to print the Identifier urn:epc:id:gid:10:1002:37, which was specified in the default build.xml file, using the ZebraPrinter instance that was discovered using CODE EXAMPLE 3-6.


CODE EXAMPLE 3-7 Printing to the ZebraPrinter Instance

// Create properties for printing

int count = 1; // default

Properties properties = new Properties()

properties.put("template", "default"); // default

properties.put("COUNT", String.valueOf(count));

properties.put("description", "Sample");

properties.put("SHIP_TO_CUSTOMER_NAME",

"Sun Microsystems");

properties.put("SHIP_TO_ADDRESS1", "Network Circle");

properties.put("SHIP_TO_CITY", "Santa Clara");

properties.put("SHIP_TO_STATE_PROV", "California");

properties.put("SHIP_TO_POSTAL", "94087");

 

String UCC = null;

if (id instanceof EPC_SGTIN_BASE) {

UCC = ((EPC_SGTIN_BASE)id).getGTIN14();

}else if (id instanceof EPC_SSCC_BASE) {

UCC = ((EPC_SSCC_BASE)id).getSSCC();

}else if(id instanceof EPC_GIAI_BASE){

UCC = ((EPC_GIAI_BASE)id).getGIAI();

}else if (id instanceof EPC_GRAI_BASE) {

UCC = ((EPC_GRAI_BASE)id).getGRAI();

}else if (id instanceof EPC_SGLN_BASE) {

UCC = ((EPC_SGLN_BASE)id).getSGLN();

 }

if(UCC != null)

properties.put("UCC", UCC);

// Finally, print the Identifier

.printTag(id, properties);