1ov PDF
1ov PDF
1ov PDF
ICS 35.240.40
J/eXtensions for Financial Services (J/XFS) for the Java Platform - Part
1: Base Architecture - Programmer's Reference
This CEN Workshop Agreement can in no way be held as being an official standard
as developed by CEN National Members.
2000 CEN All rights of exploitation in any form and by any means reserved world-wide for
CEN National Members
The CEN/ISSS J/XFS Workshop gathers suppliers (among others the J/XFS Forum members), service providers
as well as banks and other financial service companies. A list of companies participating in this Workshop and
in support of this CWA is available from the CEN/ISSS Secretariat. The specification was agreed upon by the
J/XFS Workshop Meeting of 1999-12-15/16 in Geneva and a subsequent electronic review by the Workshop
participants, and the final version was sent to CEN for publication on 2000/06-21.
The specification is continuously reviewed and commented in the CEN/ISSS J/XFS Workshop. It is therefore
expected that an update of the specification will be published in due time as a CWA, superseding this one. The
information published in this CWA is furnished for informational purposes only. CEN/ISSS makes no warranty
expressed or implied, with respect to this document. Updates of the specification will be available from the
CEN/ISSS J/XFS Workshop public web pages pending their integration in a new version of the CWA (see:
http://www.cenorm.be/isss/workshop/j-XFS/cwa-updates).
The J/XFS specifications are now further developed in the CEN/ISSS J/XFS Workshop. CEN/ISSS Workshops
are open to all interested parties offering to contribute. Parties interested in participating should contact the
CEN/ISSS Secretariat ([email protected]). To submit questions and comments for the J/XFS specifications,
please contact the CEN/ISSS Secretariat ([email protected]) who will be forwarding them to the J/XFS
Workshop.
Questions and comments can also be submitted to the members of the J/XFS Forum, who are all CEN/ISSS
J/XFS Workshop members, through the J/XFS Forum web-site http:///www.jxfs.com
Note: Java and all Java-based trademarks and logos are trademarks of Sun Microsystems, Inc. The
Java Trademark Guidelines are currently available on the web at
http://java.sun.com/nav/business/trademark_guidelines.html.
All other trademarks are trademarks of their respective owners.
Page 3
CWA 13937-1:2000
Contents
1 SCOPE........................................................................................................................................................... 4
1.1 OVERVIEW .............................................................................................................................................. 4
1.2 BASIC OPERATION PRINCIPLES................................................................................................................. 7
1.3 API SCOPE .............................................................................................................................................. 8
2 GENERAL CONCEPTS............................................................................................................................ 10
2.1 OBJECT INSTANTIATION MODEL ............................................................................................................ 10
2.2 BASIC USAGE SEQUENCE ....................................................................................................................... 10
2.3 RESERVING DEVICES FOR EXCLUSIVE USE ............................................................................................. 12
2.4 REMOTE DEVICE ACCESS ....................................................................................................................... 12
2.5 ASYNCHRONOUS DEVICE INPUT/OUTPUT AND EVENTS .......................................................................... 13
2.6 NUMERIC IDENTIFIERS USED IN J/XFS................................................................................................... 14
2.7 THREADS AND FLOW CONTROL.............................................................................................................. 14
2.8 QUEUING ............................................................................................................................................... 16
2.9 STARTUP & SHUTDOWN ........................................................................................................................ 16
2.10 USING COMPLEX DEVICES ..................................................................................................................... 16
2.11 FAILURE DETECTION AND REACTION ..................................................................................................... 17
2.12 ENSURING DEVICE INDEPENDENCE ........................................................................................................ 18
2.12.1 Device dependent mechanisms ..................................................................................................... 18
2.12.2 Vendor specific functionality (directIO) ....................................................................................... 19
2.13 POWER MANAGEMENT .......................................................................................................................... 19
2.14 UPDATING FIRMWARE IN A DEVICE ....................................................................................................... 20
2.15 NAMING CONVENTIONS ......................................................................................................................... 21
2.16 RETURN VALUES ................................................................................................................................... 21
2.17 SECURITY AND ENCRYPTION ................................................................................................................. 22
3 MAIN J/XFS COMPONENTS.................................................................................................................. 23
3.1 J/XFS PACKAGES .................................................................................................................................. 23
3.2 JXFSDEVICEMANAGER ......................................................................................................................... 25
3.3 DEVICE CONTROL ................................................................................................................................. 29
3.3.1 Object model................................................................................................................................. 29
3.3.2 IJxfsBaseControl .......................................................................................................................... 30
3.4 DEVICESERVICE .................................................................................................................................... 35
3.4.1 Object model................................................................................................................................. 35
3.4.2 IJxfsBaseService ........................................................................................................................... 36
3.5 DEVICE COMMUNICATION..................................................................................................................... 41
4 EXCEPTIONS AND EVENTS ................................................................................................................. 43
4.1 EXCEPTIONS .......................................................................................................................................... 44
4.2 EVENTS ................................................................................................................................................. 45
4.2.1 Event classes................................................................................................................................. 45
4.2.2 Registering for Events and Event Delivery................................................................................... 48
5 SUPPORT CLASSES................................................................................................................................. 51
5.1 JXFSSERVER AND JXFSCONFIGURATION ............................................................................................... 51
5.2 JXFSDEVICEINFORMATION .................................................................................................................... 52
5.3 TRACING AND ERROR LOGGING ............................................................................................................. 54
5.3.1 Overview....................................................................................................................................... 54
5.3.2 JxfsLogger .................................................................................................................................... 55
5.4 J/XFS CONSTANT CODES ....................................................................................................................... 59
5.5 TEMPORARY DATA AND GENERIC CLASSES............................................................................................ 61
5.5.1 JxfsType ........................................................................................................................................ 61
5.5.2 JxfsStatus ...................................................................................................................................... 62
5.5.3 JxfsMediaStatus............................................................................................................................ 63
5.5.4 JxfsThresholdStatus...................................................................................................................... 65
5.6 PERSISTENT DATA ................................................................................................................................. 67
5.7 VERSION CONTROL ................................................................................................................................ 67
Page 4
CWA 13937-1:2000
1 Scope
1.1 Overview
J/XFS defines a standardized interface to all common financial devices which can be used
by applications and applets1 written in the Java programming language. One of the reasons
why these new banking applications are written in the Java language is that these programs
are supposed to run on many different hardware platforms. One of the main obstacles in
doing platform independent programming is accessing devices.
One of the main goals of this standard is to allow access to banking devices in a 100% pure
Java way on both thin and thick clients, e.g. on a network computer as well as in a Linux,
WinNT, OS/2 or Unix workstation.
Another goal is to allow the remote access to devices on different machines. Additional
efforts have to be done to find and access these devices. This is the main reason why
central administration processes and an additional communication layer are also defined by
this architecture.
If only local access to devices is needed, an implementation may omit this communication
layer. No change is required to the Device Controls or Device Services. So, neither the
application programmer nor the hardware manufacturer who programs a Device Service
need be aware of whether or not a communication layer exists in the middle.
Due to the nature of network computers which are supported as clients, it is not possible to
guarantee that local persistent storage possibilities exist on each client. Therefore, any
configuration information must be kept on a central server. If local storage exists and no
central configuration possibilities are required, all configuration information can also be
kept on the local workstation.
The basic architecture of J/XFS is similar to the JavaPOS2 architecture. It is event driven
and asynchronous.
Three basic levels are defined in JavaPOS. For J/XFS this model is extended by a
communication layer, which provides device communication that allows distribution of
applications and devices within a network. So we have the following layers in J/XFS:
Application or applet
Device Control and Manager
Device Communication
Device Service
The Device Control API defines the way a Java application or applet can communicate
with a specific device. Additionally, the Device Control layer contains the central Device
Manager which organizes access and location of the services. It is the central coordinating
instance in any Java VM which must access financial devices.
The Device Communication Layer is the layer which resolves the sharing of devices. It is
invisible to the application. The only exception is that network errors are presented to the
application. It must be able to cope with lost connections.
The Device Service is the layer supplied by the device manufacturer for use with J/XFS. It
has a defined API which allows the Device Control and Device Communication layer to
request device actions and translates them into the device specific commands which are
then sent to the physical attached device. The way of connecting to the local device is not
defined in this standard, it is rather left to the service provider. In the case of devices which
attach through the serial or parallel ports the Java CommAPI may be used. Thus, the
Device Service layer may not be 100% pure Java but the complete basic infrastructure of
J/XFS is.
1
J/XFS is designed to be also usable by applets in a browser e.g. on a network computer. So, for the remainder
of the document, application also always means applet.
2
JavaPOS (Java point of sale) is an initiative for the retail industry with the goal of providing unified device
access to POS devices. See http://www.javapos.com .
Page 5
CWA 13937-1:2000
Application developers program against Device Control objects and the Device Manager
which reside in the Device Control Layer. This is the usual interface between applications
and J/XFS Devices. Device Control objects access the Device Manager to get access to an
associated Device Service. And the Device Service objects finally provide the functionality
to access the real device (i.e. they are like a device driver).
Java applications or applets run in a Java virtual machine (Java VM), possibly embedded
in a WWW browser. Under some operating systems (i.e. JavaPC) only one JavaVM can
run in the system (i.e. it allows multiple threads in the program but not multiple programs).
There the J/XFS layers must run in the same process context as the application or applet.
The bigger operating systems like OS/2, Windows NT or Unix can run multiple JavaVMs
in parallel. This must also be possible with J/XFS.
Thus, the design of J/XFS must cope with the following scenarios:
1. A single JavaVM is present on a workstation and is running the application or applet
(J/XFS Client) which accesses only local devices.
2. A single JavaVM is present on a workstation and is running the application or applet
which also accesses one or more remote devices (which are physically attached to
another workstation).
3. Multiple JavaVMs, each running an application or applet, run on the same
workstation. As ports through which devices are connected (i.e. the com port) cannot
be accessed in parallel only one of the running applications must control the local
devices. For this scenario there is a distinction of whether these multiple applications
really run in parallel or if they are started only one at any time.
Only in the very simple first case it is possible to omit the communication layer. A device
access from an application in one JavaVM to another one running on the same machine is
similar to accessing a device on another machine as also interprocess communication is
needed.
Workstation
J/XFS Client
Application or applet
DeviceControl JxfsDevice
Manager
JxfsConfiguration
DeviceService
CommAPI or JNI
physical device A
The application requests the device from the DeviceManager and accesses the device via
the DeviceControl. The DeviceControl is directly connected to the DeviceService for the
device. The JxfsDeviceManager controls both objects. The whole configuration may be
kept locally, either hard-coded in JxfsConfiguration object or somehow configurable on
disk or in memory.
The next diagram illustrates the basic architecture for the case 2 (Remark: Both Client1
and Client2 access the server in the same way. The connections for Client1 are not shown
here):
Page 6
CWA 13937-1:2000
W orkstation A W orkstation B Server
J/XFS Client1 J/XFS Client2
A p p lica tio n o r a pp le t Application or applet
JxfsConfigServer
JxfsDevice JxfsDevice (Configuration
DeviceControl M anager DeviceControl
M anager repository)
JxfsConfiguration JxfsConfiguration
DeviceCommunication DeviceCommunication
Jxfs
DynamicServer
DeviceService DeviceService (Device
availability
information)
CommAPI or JNI CommAPI or JNI
The clients have to start the J/XFS infrastructure upon startup. When the
JxfsDeviceManager is instantiated it queries (via a JxfsConfiguration object) the central
information repository relating to all J/XFS devices. This contains the configuration
information for each workstation (the available devices, where they are attached, which
service class handles them, whether a device can only be accessed on the local machine or
also from a remote workstation, needed initialization information for each local device
etc.). The means with which this information is stored is not within the scope of J/XFS. It
might be a file, a database or an object repository. Only the access API is defined.
After successful initialization any locally connected devices which should be available to
other workstations are registered with the JxfsDynamicServer. It thus contains up-to-date
information on the availability of the devices. Any other workstation can query for a list of
available remote devices there.
In the case 3 mentioned on the last page the J/XFS Client1 and J/XFS Client2
processes may run on the same workstation. If it is guaranteed that only one process runs at
any time no problems arise. If they run in parallel, however, the following scenario must be
used:
W orkstation A Server
J/XFS Client1 J/XFS Client2
Application or applet Application or applet
JxfsConfigServer
JxfsDevice JxfsDevice (Configuration
DeviceControl Manager
DeviceControl Manager repository)
JxfsConfiguration JxfsConfiguration
DeviceCommunication DeviceCommunication
Jxfs
DynamicServer
DeviceService (Device
availability
information)
CommAPI or JNI
physical device A
Page 7
CWA 13937-1:2000
Why is it required that the J/XFS client2 has no local device access? Because it is
impossible that multiple Device Services for the same physical device are started. And why
that? Because access to the device through the physical port it is connected to is restricted
to 1 process only.
So, the configuration of J/XFS must cope with this fact. Several J/XFS clients running in
parallel on one workstation must be differently configured. One must be clearly defined to
be the J/XFS client which instantiates all the DeviceServices of the local devices and any
other client running on this workstation must now access these devices as if they were
remote.
Additionally, the first, controlling, J/XFS client must also be the first to start up and the
last to shut down. If not, the others wont be able to access the devices any longer (because
the DeviceService is no longer available).
The correct way to configure such a system to use J/XFS would be to use a (likely very
small) J/XFS client application which has the sole need to instantiate the DeviceServices
needed to access all the local devices. It can be started automatically during the boot
process of the workstation and will not terminate until the shutdown of the computer. The
other applications are now free to access this device as if it were remote.
First, we are giving a short overview about what happens if a device is accessed (a small
distributed sample scenario). It is illustrated in the following graphic and used to describe
the control flow in the following description.
J/XFS Client1 (applet or application)
Application J/XFS repository
6: 1:
ge ne
tDe w
vic JxfsDeviceManager
e
9: access
2: que
ryC o n fi g F JxfsConfigServer:
7: o r ( C li
ne e n t1 )
w
5: Client1: PassbookPrinter,remote
reg Client2: JournalPrinter,remote
ist
4: g
ev
ice
ene
gen
JxfsPassbookPrinter
era
ater
JxfsDynamicServer:
te
8: connect to
registeredDeviceTable:
Client1: PassbookPrinter, ...
JxfsPassbookCommsListener Client2: JournalPrinter, ...
t to
o nnec
4b: c
A_PassbookPrinterServiceImplementation
Java CommAPI
PassbookPrinter
On each client which participates in J/XFS device access, the application or applet
generates a new JxfsDeviceManager object upon startup (1). It does the initialization of the
J/XFS subsystem by first querying the repository for its configuration data (2). Then it
instantiates all the Device Services for the locally connected devices (3). If configured for
remote access also the objects responsible for enabling this remote connection are
generated (4) and connected to their DeviceService (4b). If all is successful, the now
available DeviceService is registered at the central directory where other J/XFS clients can
query for accessible devices (5).
If the local application or applet now wants to access a J/XFS device, it has to ask the
DeviceManager for the device. This happens via the getDevice() method (6). During this
method the DeviceManager generates a Device Control (7), locates the DeviceService and
Page 8
CWA 13937-1:2000
connects it to the Control (8) and returns the Device Control to the application which can
now start to use the device (9).
If the requested device were on a remote machine, then the DeviceManager would, in the
getDevice() method, first ask the JxfsServer for the location of the requested device and,
instead of connecting the generated DeviceControl to a local DeviceService, use a remote
object to establish a connection to the remote device. Note that the DeviceControl itself
(and with it the application) would not notice any difference.
In order to minimize network traffic, the design of the Device Service API was done so
that the granularity of the device access methods is as big as possible without impacting
functionality.
If a Device Control is requested, the JxfsDeviceManager has to load the corresponding
classes and connect the Device Control to a Device Communication or Device Service
object. It also keeps track of whether a Service (or Communication) object already exists
for the specified device. If true, it connects this to the Device Control, if not, it generates it.
There exists exactly one Device Service object for each physical device. If additional
requests arrive, they are all routed to the same Device Service object. But there is no
restriction on the number of DeviceControl objects accessing the device within J/XFS!
Thus, it is the duty of the service object to synchronize concurrent commands to a device.
There are two types of methods within J/XFS: Synchronous and asynchronous methods.
The former ones are always used for small functions which do not need to access the
device, like e.g. querying the version of an object, querying the device status (which is held
in the DeviceService) or repository access. If synchronous methods fail they throw an
JxfsException with additional information.
Any operation on a device is asynchronous. This means, that it immediately returns an
identificationID for the requested operation to the application. The operation itself is
queued and executed in the order it arrives at the DeviceService (except if the device is
claimed, see the later chapter Reserving devices for exclusive use for details). During
execution on the device the DeviceService sends one or more events to the application.
Intermediate Events are sent to inform of intermediate steps during the execution of the
command, and as soon as the operation is completed, one OperationCompleteEvent is sent.
Both events also contain the identificationID to enable the application to uniquely identify
the operation the event belongs to.
Additionally, if the device status changes, the DeviceService has the possibility to send
StatusEvents asynchronously to the application.
For each of the defined three event types the application can choose whether or not it wants
to receive these events by calling the respective addListener method of the DeviceControl.
The above explanations are only meant to give a short overview of the design of J/XFS,
they are all expanded in the following chapters.
Application or applet
2 1 4,5
DC DM Support
Objects 6 Configuration
3
DS
Page 10
CWA 13937-1:2000
2 General Concepts
In the following section several of the key concepts in the J/XFS design are described in
detail. This information provides the foundation for the API design found in the following
chapters.
This is a very important part of this document as it serves to give a common understanding
of how the properties, methods and events are to be used in a real J/XFS compliant
application or applet.
Singleton objects are objects which are instantiated exactly once in a Java VM. They are
the JxfsDeviceManager and the JxfsLogger.
The applications access a device through its Device Control object. A single application
may access multiple DC-objects for the same device (perhaps in different parts of the
program). If an application remotely wants to access a device is also gets a DeviceControl,
and a remote connection to the DS is established. Thus, Device Controls for the devices
can occur multiple times.
The Device Service for a specific device manages access to this device. It is instantiated
only once for each device.
The following graphic gives a short overview about this. For the remote case the
communication comes in via an object which looks just like another Device Control
accessing the same Device Service object for the device.
App1
Device-
Manager
Remote
DC1 DC2 connection
DS
Hardware
Java VM
If an application or applet wants to gain exclusive access to a device, it uses the claim()
method on its Device Control. The basis is the control object, i.e. that if an application gets
two control objects for the same device a claim() to the second one will fail, even though it
is used by the same application. So, an application can either use one control for all its
activities with a device or use the claiming mechanism to synchronize its different program
parts if necessary.
The synchronization itself is done in the Device Service layer. The Device Control only
routes the requests to the DS and cannot make a decision on its own. The Device Service
must decide whether or not a claim() is successful. The same applies for the method calls.
Only the Device Service can decide whether or not a method invocation is executed or
queued for execution.
After the start (big dot) they are uninitialized , and an open call brings them to Working
(everything ready). During their operation devices may be claimed and released. Also, if an
error occurs, they do only temporarily switch to one of the error states and after having it
fixed they return to their previous state. It is also possible that the device switches to power
save mode if it is not used for a longer period of time. It leaves this state if any command is
issued.
If an error already exists like HardwareError (maybe the device is defective) or a
UserActionError (paper missing etc) then the open succeeds anyway but the status reflects
the error state.
Only a device that is not claimed can be closed and unregistered by the application.
Any device state change is reported by a StatusEvent to the application (except for the first
change from registered_but_not_open to Working as this is only of interest to the DC
calling the open() which is informed via an OperationCompleteEvent). For details see the
description of the StatusEvent in the Events chapter.
Page 12
CWA 13937-1:2000
2.3 Reserving devices for exclusive use
If an application or applet accesses a device it is sometimes necessary to restrict access to
this device for other applications or applets for a certain amount of time. This can be
needed if multiple operations must be done sequentially and not interrupted by operations
from other applications. This is made possible by using a claim() method to lock the
device and a corresponding release() method, which frees the device again.
There is, however, no method in J/XFS which requires the use of the claim/release bracket.
The following sequence diagram outlines the basic concept of claim and release (and also
illustrates nicely the event send mechanism). Please note that the application does not
directly access the Device Service as depicted here but of course issues any calls and
receives any events via their DeviceControl object. The reason the Device Service is
shown here is that it is the coordinating object.
If an application starts the claim request the Device Service queues this request and goes to
a claim_pending state. It will not grant the claim until any operations still in its queue are
finished (3,4,5). After the claim was granted any connected DC is informed via a
StatusEvent (6,7). From the moment the claim request arrives any incoming new requests
from other application (8,9) are queued for execution after the release. Additional claim
requests (14) have to wait for the release of the current claim.
The claim is only granted if a specified timeout has not expired before all other running or
pending operations are completed (as happens in 14 - 17).
Likewise the release must be accompanied by a timeout value which defines how long to
wait until pending operations are finished (18). Only after that the release returns (20) and
the according StatusEvent is sent to every DC (21,22). If more claim requests are in the
queue, the next one is granted (24). If not, every Device Control is free to directly access
the device operations again.
In some circumstances (e.g. for very small, quick operations) it may occur that an Event is
returned to the application (via the call to one of the <eventType>occurred() methods)
before the method call itself has returned, thus providing the application with an
identificationID. Pitily this cannot be remedied by the J/XFS infrastructure itself as the
same problem may occur because the application is too slow of informing its listener
object of the arrived id.
Page 14
CWA 13937-1:2000
Thus, the application must be prepared to either accept events for which the
identificationID is not yet known and buffer them or prevent such a situation.
One simple and advisable way to prevent such a situation this is to simply declare the
<eventType>occurred() method of the event listener instance "synchronized" and also
synchronize the event provoking call on that instance.
Thus, the event delivery is postponed until the method call has returned.
The following diagram outlines the different threads involved in the delivery of events:
StatusEvent
Listener Queue
e n = new StatusEvent() Queue
e1 l1
IJxfsEventNotification e2 l 2
ecb 2 . fireStatusEvent( e n )
ecb 2 l 1 . statusOccurred( e 1 )
l 2 . statusOccurred( e 1 )
...
...
l n . statusOccurred( e n )
ecb n . fireStatusEvent( e n )
ecb n
Device Control 2
Device Control 3
Each thick black arrow represents one thread. The Device Service generates an event and
delivers it to every Device Control it is connected to (Shown here are three DCs). The
threads only add the new event to the respective queue in the Device Control and
immediately return to the DS. Now a separate thread running in the DC always picks the
next available event in the queue and delivers it to all application objects which have
Page 16
CWA 13937-1:2000
registered to receive the Status events (Listener queue) via their listener methods, here:
statusOccurred(). As a result the DS thread is always decoupled from any application level
processing ... a very desirable feature.
As explained above, a second identical queue and delivery thread exists for the
OperationComplete and Intermediate events.
2.8 Queuing
There are several places in the J/XFS architecture where queuing takes place:
As stated above, each Device Control has two queues where the events are inserted
and each one is read by a single thread which delivers the events to the application.
As all operations in J/XFS are asynchronous the Device Services internally have to
administer a queue which collects the requests and works on them one after the other.
If multiple claim requests arrive at the Device Service it must queue them until their
respective timeouts occur and grant the claim to the next queued control after it was
released by the current claim holding control.
The shutdown of the controlling application or applet is the shutdown of the J/XFS
infrastructure. Upon shutdown the application or applet should tell the Device Manager
about what is going to happen, so that it can shut down all the services it provides. This is
achieved by the application or applet calling DM.shutdown() upon ending.
In this method the DeviceManager calls any instantiated Device Service and Device
Communication objects and instructs them to shut down. They have to inform any of their
peer Device Controls, which have to notice the status change and deactivate any device
access.
There are additional methods in the Device Manager to control Service instantiation and
destruction of local DSs: start and stop. Using stop the application can intentionally stop
(or shut down) the specified DS only. It can then use start to try to re-start the stopped
Device Service. If the device is accessed locally, a getDevice() call also implicitly issues a
start command if it is not yet started (thus allowing an Activation-on-demand behavior).
For a more detailed description see the explanation of the shutdown() method in the
chapter on the JxfsDeviceManager, the Device Control and the Device Service.
Assume that there is no device type which allows Text in- and output in J/XFS. Then, as an
example, assume a vendor of a banking printer has added an LCD panel to it where some
information can be displayed to the customer.
When writing the J/XFS Device Service for its printer the vendor has to implement all the
defined properties, methods and events for the printer device service. He decides that some
default texts are displayed on his panel during these operations.
Then, he implements the directIO method to allow an application to control the LCD. In
his document he states that to show something on the LCD the application can use a call to
3
directIO with a command-parameter of ACME_PRT_SHOW_LCD and a data object
(subclassed from JxfsType) which contains the message.
A banking application which knows of this printer can now use the directIO call to show
specific messages on the printer's LCD. Other printers would simply ignore the given
command by returning JXFS_E_NOT_SUPPORTED (which is the default behavior for
this call). Via the getDeviceServiceDescription() method the application can find out
whether or not this is the printer with the LCD panel.
If the new functionality is for data input, then a call to the directIO method would only
activate the possibility of receiving data and return an operationID and later, when the data
arrives, either an Intermediate or OperationComplete event (or both) are sent which the
application can receive (if it has registered successfully beforehand). It contains the
operationId so the application knows that these events belong to the previously issued
directIO command.
If a financial device or the appropriate device service for this device is able to cope with
the power save mode internally without performance impact to the application it is
encouraged to do so.
But in some cases the application should be aware of the current power mode of a device
to optimize the performance. Imagine a dispenser inside a ATM goes into a power save
mode that takes 30 seconds to come back into operational mode. If now a transaction
starts that involves the cash dispenser and the cash dispenser begins to wake up the
moment it shall begin to work on bank notes then this will have a performance impact of
30 seconds to the transaction. But if the application begins to wake up the cash dispenser
in the moment the customer enters his identification card, there is nearly no performance
degradation for the transaction.
3
The numeric value of these constants is left to the device service programmer. It must, however, have a value
above JXFSDIRECTIO_OFFSET.
Page 20
CWA 13937-1:2000
The way power management is achieved is highly device specific. J/XFS does not define a
way to specify when and how to enter power save mode and the details on configuration of
these features, this is left to the Device Service implementations.
There are, however, certain general methods which are defined here so the application is
able to react. They are
Allowing to query a devices power save capability isPowerSaveModeSupported().
Querying whether or not a device is in power save mode (and thus may take longer to
finish with a following operation) JxfsStatus, boolean property powerSave
Actively waking the device up bringing it up to full functionality (Any requested
operation to a device also implicitly wakes it up) wakeUpFromPowerSave()
Sending events whenever power save mode is entered or exited StatusEvents
JXFS_S_POWERSAVEON and JXFS_S_POWERSAVEOFF
For all these functions J/XFS has installed the mentioned mechanisms. Anything which
serves these power management functions has Power save in its name, thus making it
easy to spot these things in the J/XFS architecture.
See the remaining chapters for details.
Basically there are two different methods of updating the firmware: automatic and
manual.
The automatic case occurs if the Device Service detects a need to update during normal
startup (open) of a device. The exact behavior must be decided by the Device Service class.
As no possibility exists to inform the user about the process, the automatic updating should
not take longer than a couple of seconds, so the user will not think the device is non-
responsive and perhaps turn it off during the update.
The manual update process is under control of the application (either a special J/XFS
enabled program or part of a banking application) which could look like this:
For the basic definitions of the above constants see J/XFS constant codes on page 59.
Any class or interface, especially those visible to the application (ex: Device Controls)
should obey the JavaBeans naming convention.
Also, it may be desirable to encrypt all data which is send over the LAN between the
workstations and the server, as well as between the peer-workstations sharing a device
using J/XFS.
This is, however, also not a task defined in the J/XFS Version 1.0. It is rather left to the
TCP/IP installation and add-on security products to ensure that the data transfer is secure.
We assume that a solution to this is or will be available for use without the necessity to
change the J/XFS structure. One possible option here would be to use RMI over SSL.
Page 23
CWA 13937-1:2000
The lines represent dependencies between the different packages. The most important
concept here is that the Device Service layer does not depend on the Device Control layer
as only then can the chore of transferring data over a network be invisible to the Device
Service as well as to the application.
In addition to the packages shown above (which make up the basic J/XFS infrastructure)
additional packages with the service implementations of the hardware manufacturer are
used.
The following table gives an overview of which classes are put into which package:
3.2 JxfsDeviceManager
The JxfsDeviceManager (DM) is a static object where device requests are routed to. There
is exactly one DM in each Java VM.
Its main duties are
Keep lists of devices / services / communication connections.
Handle service instantiation and connect Device Controls, Device Communication and
Device Services
Query and write configuration data.
Shield Device Controls and Device Services from using a specific set of Java APIs for
configuration lookup and object creation (e.g. JSD and JSL) to gain flexibility.
Make controls and services simpler and more straightforward to program.
Communicate with a server to request device information on both local and remote
devices (making it transparent for the device layers).
Install any necessary classes so that other workstations can remotely access the
devices.
Register the devices which should be accessible by remote applications at the
JxfsServer.
Except for the initialization and finalization phase most applications will not need to use
the DM very often. Access to device specific functionality is solely available through the
respective Device Controls.
The DM is used by the application for the first Device Control generation and for special
purposes such as getting lists of available devices.
The detailed description of the DMs interface follows.
If the application wants to use a device, it must call the Device Manager's getDevice()
method. If no error is thrown then this returns a valid reference to a DeviceControl of
the requested type.
What happens internally during such a request?
First, the DM checks if the requested device is attached locally. If yes, it connects the
corresponding DS (or implicitly starts it if it is not yet instantiated), generates a new
DC and returns this to the user.
Page 27
CWA 13937-1:2000
The usual scenario is depicted in the graphic (where also a following open is shown):
void removeKeyValueChangeListener(KeyValueChangeListener l)
throws JxfsException
Remove the given KeyValueChangeListener object from the listening list.
JxfsVersion getDeviceManagerVersion()
Return the version object for this Device Manager.
boolean addStatusListener(StatusListener l)
boolean removeStatusListener(StatusListener l)
With these methods the application can register as a listener to receive the
StatusEvents from the DeviceManager (Returning true if the listener was successfully
added or removed).
The DeviceManager informs of general things which are happening in the J/XFS
infrastructure using Status events.
Currently, StatusEvents with the following Id's are defined:
JXFS_S_SHUTDOWN A shutdown was recieved by the DeviceManager (see
below)
JXFS_S_ Communication is broken down.
REMOTEFAILURE
JXFS_S_SERVICE_ A running DeviceService was stopped. In the details
STOPPED parameter the logical name of the DS is given.
JXFS_S_SERVICE_ A stopped DeviceService was started. In the details
STARTED parameter the logical name of the DS is given.
void shutdown();
Prepare the shutdown of the J/XFS infrastructure. The Device Manager calls the above
stop() method for all local devices. Finally it deactivates the logger by calling its
shutdown() method, disables itself and returns control to the application.
Page 29
CWA 13937-1:2000
In the following only the IJxfsBaseControl interface is described in detail; all the
subclasses of this interface are described in the respective device class documentation.
Page 30
CWA 13937-1:2000
3.3.2 IJxfsBaseControl
Public methods
The methods all Device Controls must support and which define the basic device behavior
are:
int open() throws JxfsException;
This method must be the first method an application calls in a newly generated Device
Control in order to use all other functions. Exceptions are the addXXXListener
methods and getStatus()). A call to another methods throws a JxfsException with code
JXFS_CLOSED.
This is the first time the device is physically accessed. It is asynchronous4 and returns
an identificationID. After the open completed an OperationComplete event with
operationID = JXFS_O_OPEN and the given identificationID is sent to the
application. The result is either JXFS_RC_SUCCESSFUL or one of the error codes.
After the open operation has been issued (but even before the OC Event has arrived)
any other method is callable. Operation requests are queued for execution, and if the
open fails, they are discarded.
But, of course the correct behavior for an application is rather to wait for the OCEvent
of the open() and only then start using the device.
The open() must only fail for severe, unrecoverable errors. Minor defects should be
noticed by the DS but the open() should succeed. For details on this please also see the
device specifications detailing more on the correct open() behaviour.
Even if the open() fails, Status events are generated to inform the application that the
Device status has changed. The application may then re-try to open the device.
Possible exception codes are:
JXFS_E_UNREGISTERED Device is not registered at the Device Manager. It
must either be instantiated using new(), which is not
allowed, or has already been deregistered at the
Device Manager which disables this control
completely.
JXFS_E_OPEN Device is already opened.
JXFS_E_REMOTE Communication error during remote call
4
The reason that open and close are defined as asynchronous methods is that they also access the device. The
generic J/XFS rule for device access requires asynchronous behavior (see page 13).
Page 31
CWA 13937-1:2000
If timeout is equal to JXFS_FOREVER (-1) then the operation waits as long as needed
for the device to become available.
The return value is equal to TRUE if claim() succeeds. The return value is equal to
FALSE if claim() has timed out.
An application should release the claimed device as soon as possible.
Possible exception codes are:
JXFS_E_UNREGISTERED Device is not registered at the DM.
JXFS_E_CLAIMED Device is already claimed by caller.
JXFS_E_CLOSED The open call has not been issued yet.
JXFS_E_REMOTE Communication error during remote call.
JXFS_E_PARAMETER_IN Invalid value for timeout parameter
VALID
boolean addIntermediateListener(IntermediateListener l)
boolean addOperationCompleteListener(OperationCompleteListener l)
boolean addStatusListener(StatusListener l)
These methods are used by the application to register as a listener to receive the given
type of events. Returns true if the listener was registered successfully.
Page 32
CWA 13937-1:2000
boolean removeIntermediateListener(IntermediateListener l)
boolean removeOperationCompleteListener(OperationCompleteListener l)
boolean removeStatusListener(StatusListener l)
These methods are used by the application to register as a listener to receive the given
type of events. Returns true if the listener was removed.
String getDeviceName();
Get the unique device name for this device (Type and distinction between similar
devices, e.g. port name). Used to identify the device. This is the logical name key
given in the configuration repository.
JxfsVersion getDeviceControlVersion();
Return the version object of this Device Control. See the chapter on versioning for a
detailed explanation.
5
What's the difference between version and functionality?
It could be the same firmware, but another version, i.e. it is the firmware for a chip card reader with German
ZKA standards, but a newer version. Or it could be a firmware with other functionality, i.e. the firmware for a
French chip card shall be loaded, but the chip card reader currently contains the firmware for the German ZKA
standard.
Page 34
CWA 13937-1:2000
For an exact description of how to use this method see the explanation in the chapter
on 'Vendor specific functionality'.
Possible exception codes are:
JXFS_E_UNREGISTERED Device is not registered at the DM.
JXFS_E_CLOSED Device has not been opened yet
JXFS_E_CLAIMED This method is not available at this time because the
device is currently claimed for exclusive access by
another control.
JXFS_E_NOHARDWARE Device is not connected to the workstation
JXFS_E_NOTSUPPORTED Operation not supported by this device
JXFS_E_REMOTE Communication error during remote call
Internal methods
There are additional methods necessary to successfully connect the Device Control to its
Device Service and the Device Manager. They are only for J/XFS internal use and are only
briefly outlined here:
void registerService(IJxfsBaseService myService, JxfsDeviceInformation di)
throws JxfsException;
This method is used by the Device Manager to initialize the Device Control by
providing a reference to the service object itself. The Device Manager also provides
the appropriate Device Information for the DCs use.
void connectionFailure();
This method is called by any communication layer to inform the Device Control that
the connection to the DS is broken.
The Device Control now has to approve this fact by using its deregisterService()
functionality and must send the application a StatusEvent with
JXFS_S_REMOTEFAILURE.
The exact details of the connection failure are written to the logger by the
communication layer.
Page 35
CWA 13937-1:2000
3.4 DeviceService
In the Device Service layer the interfaces for the hardware vendors (HV) device drivers
are defined. In order to be compliant an HV must implement the interface.
If possible, it should be done in 100% pure Java. Note that the CommAPI is not yet
available for all platforms, and there are some services that may use other interfaces to
access the device. One alternative could be JNI, the Java Native Interface. For each Device
Control class there is a corresponding Device Service interface which has to be
implemented in order to access the physical hardware.
The diagram depicts the inheritance tree of the device service interface classes. Also shown
are some of the available mixin interfaces to add special functionality (e.g. the support for
motorized card interface for the MagStripe and ChipCard devices). These are the ones
which do not inherit from the IJxfsBaseService interface.
All the methods in the control interfaces are reflected in the methods of the service classes.
The Device Service class must synchronize access to it from multiple Device Controls and
guarantee that after a successful claim any operation the Device Control that got the claim
does is sequencial and precedes any other arriving requests. In order to support control
identification for event delivery more easily, an additional parameter (int control_id) is
passed into every method as the last parameter. The Device Control gets this identifier
from the Device Service after registering there. If the device is claimed by a control the
service class can thus lock out any other accessing control.
Page 36
CWA 13937-1:2000
In the case of complex devices (which are devices that implement more than one J/XFS
device type in a single service), an additional claim() always succeeds if it is issued by a
control that represents a different device but is also held by the control issuing the original
claim. This means that a service that represents more than one subdevice allows the
claiming of each subdevice unless there is only one claim() method in the service. See the
definition of claim below and in the Device Control description.
3.4.2 IJxfsBaseService
The methods all services must support and which define the basic device behavior are:
int open(int control_id) throws JxfsException;
This method must be the first method a control (identified by control_id) calls in a
newly generated Device Control in order to use all other functions. Exceptions are the
addXXXListener methods and getStatus()). A call to another methods throws a
JxfsException with code JXFS_CLOSED.
This is the first time the device is physically accessed. It is asynchronous6 and returns
an identificationID. After the open completed an OperationComplete event with
operationID = JXFS_O_OPEN and the given identificationID is sent to the
application. The result is either JXFS_RC_SUCCESSFUL or one of the error codes.
After the open operation has been issued (but even before the OC Event has arrived)
any other method is callable. Operation requests are queued for execution, and if the
open fails, they are discarded.
But, of course the correct behavior for an application is rather to wait for the OCEvent
of the open() and only then start using the device.
If the OC event returns success the device is connected to the workstation and device
status is correct.
The open() must only fail for severe, unrecoverable errors. Minor defects should be
noticed by the DS but the open() should succeed. For details on this please also see the
device specifications detailing more on the correct open() behaviour.
Even if the open() fails, Status events are generated to inform the application that the
Device status has changed. The application may then re-try to open the device.
The following general exceptions are possible (in addition to any device specific
exception codes):
JXFS_E_OPEN Device is already opened.
JXFS_E_REMOTE Communication error during remote call
6
The reason that open and close are defined as asynchronous methods is that they also access the device. The
generic J/XFS rule for device access requires asynchronous behavior (see page 13).
Page 37
CWA 13937-1:2000
7
What's the difference between version and functionality?
It could be the same firmware, but another version, i.e. it is the firmware for a chip card reader with German
ZKA standards, but a newer version. Or it could be a firmware with other functionality, i.e. the firmware for a
French chip card shall be loaded, but the chip card reader currently contains the firmware for the German ZKA
standard.
Page 39
CWA 13937-1:2000
JXFS_E_REMOTE Communication error during remote call
There are a small number of additional methods which are used by the Device Manager to
initialize the Device Service:
8
We cannot use a direct reference to the Device Control class here because of the possibility of network
transfers which hide the originating type of the class from the DS.
Page 40
CWA 13937-1:2000
JXFS_E_OPEN Device is still opened.
JXFS_E_REMOTE Communication error during remote call
Application
DC Api
DeviceControl
DS Api
DeviceCommunication
DC Api
DS Api
DeviceService
It implements the Device Service interface for the Device Controls to use. For the
DeviceService it implements the same interface as the Device Controls do -- which is
mainly the IJxfsEventNotification - interface.
For the simpler case of only local device access, the Device Communication layer may be
omitted and the JxfsDeviceManager is reduced to an interface to a registry (JSD, a file or
other available storage).
Client1 Client2
Device
Control
Device Device
Communication Communication
Device
Service
Phys. device
The above chart tries to give a short sketch of how the communication classes enable the
sharing of devices across a network.
To the Device Control the Device Communication looks exactly like a Device Service, and
to the Device Service on the other side of the connection the Device Communication looks
exactly like a Device Control.
The existence of a network communication layer must not be known to the application.
The J/XFS architecture, however, has some features to enable this communication layer.
Page 42
CWA 13937-1:2000
Probably the most important feature is that all operations of the devices are designed to be
idempotent. This means that to issue an operation any relevant parameters are usually
given in the same method call, there is no requirement that for a single operation multiple
method calls are necessary. This minimizes the effort for error handling which needs to be
done in a communication layer as well as in the application.
Page 43
CWA 13937-1:2000
The application itself can decide whether or not it is interested in these event messages
since it must specifically register to receive the events. It can register for each of the
different event types.
As a common guideline on when to use Exceptions vs. Events it can be said that, as
Exceptions are a more direct way to inform the application of some error condition they
are used in preference to Events.
But, as in J/XFS all the methods involving the device are asynchronous, there is, apart
from instant parameter checking etc., no other way to inform the application than via
events.
Please also note that currently there is no such feature as returning some interaction values
back to the Device Service (such as continue / retry / cancel). As banking devices are very
sensitive to the completion of an operation, an operation which encounters for example an
out of paper condition is cancelled and must be re-issued by the application (after action
like refilling the device with paper was taken).
There is intentionally no such event like an ErrorEvent. Any information the application
needs in the case of an error is the error code. This is delivered via the appropriate
OperationCompleteEvent. The details regarding the error are only of interest for a
Page 44
CWA 13937-1:2000
supervisor application which can gather this information from the Logger. See the chapter
on Tracing and error logging on page 54 for details.
4.1 Exceptions
The standard exception within J/XFS is the JxfsException. It is thrown wherever an
exception is needed and contains the following parameters (all except errorCode may be
empty:
Parameter Type Meaning
errorCode int The error code. One of the defined JXFS_E_...
codes.
errorCodeExtended int An extended error code. This can be a system or
device dependent error code.
description String Textual description of the error.
origException Exception The original exception which was caught and
replaced by this JxfsException. A standard
sample would be that a RemoteException is
caught and a new JxfsException with error code
JXFS_E_REMOTE is created. Then the original
exception is put into it if the application wants
to analyze the exception further it can get it
from here.
/////////////////////////////////////////////////////////////////////
//
// JxfsException
//
// Exception class used to report all J/XFS errors.
//
/////////////////////////////////////////////////////////////////////
package com.jxfs.events;
4.2 Events
All possible events are categorized and belong to one of the event classes outlined below.
The common base class for any J/XFS event is the JxfsEvent.
JxfsEvent
This event class contains the generic variables for all the events. It extends
java.util.EventObject. It is not used on its own but serves as a base class for the other
J/XFS event types.
In the following table all relevant methods are outlined
Method Return Meaning
getWhen() Date Contains the timestamp when the event was
created.
setSource(Object void Sets the source of this event. This is filled
source) with the Device Service object (as the events
are generated here), but is replaced by the
Device Control object before it is passed to
the application. Method
getSource() IJxfsBaseService Returns the source of the event. (Inherited
or from the EventObject class).
IJxfsBaseControl
Interface class:IntermediateListener
Listener method: intermediateOccurred(IntermediateEvent e)
OperationCompleteEvent
An OperationCompleteEvent is always sent when a previously started operation
terminates. It is sent only to the Device Control which started the operation.
It can either just inform if a successful completion of an output command (e.g. printed),
returns the data of a requested input operation or gives information if the operation failed,
perhaps returning a partial dataset.
The operationID and identificationID identify the exact operation; the result code contains
the result of the operation, the optional data object can deliver additional data.
If the operation requested is a data input operation, then THIS EVENT MAY BE
SUBCLASSED and this subclass will be delivered INSTEAD of an operation complete
event. To easily identify these events they all start with the letters OC followed by the 3
digit device type identifier to mark them as subclasses of the OperationCompleteEvent and
give a clear indication as for which device type this event is valid. See also the chapter on
naming conventions later in this document and the sample in the above object diagram
(OCPTRReadDataEvent).
Why do we do that?
For several input operations the data returned can be quite complex, and instead of hiding
the data in the generic variable object it is easier for the application to directly query the
data from the event. Since the application must register separate listener methods with the
Device Control to receive these events, the application code to handle these events will
thus be more straightforward and less error prone.
An example would be the OCPtrReadDataEvent of the Printer classes. They deliver a
complex array of read fieldnames and their values. To receive it the application must do a
addOCPtrReadDataListener(myHandle).
Page 47
CWA 13937-1:2000
The exact parameters of the event are defined in the Device Control definition of every
device type.
StatusEvent
A StatusEvent is sent if the status of the device has changed. The reason for this may either
be a change due to an operation (such as paper low) , or it may occur due to user
interaction (such as device made offline).
This type of event is sent to ALL the connected Device Controls.
All the connected Device Controls (and thus the application or applet) are informed of
certain changes of the device status. They receive a StatusEvent with the corresponding
status and with a null details object in the following cases:
status Meaning
JXFS_S_CLAIMED Sent if the device was claimed.
JXFS_S_RELEASED Sent if the device was just released by a Device
Control which had claimed the device.
JXFS_S_HARDWAREEROR Sent if a hardware error was detected by the Device
Service.
JXFS_S_USERACTIONERROR Sent if an error was detected which is resolvable by
user intervention.
If a more specific StatusEvent is generated regarding
the error (e.g. a TONER_OUT) then NO additional
event with this id is sent.
JXFS_S_WORKING Sent if an error has been fixed to indicate that the
device is working again.
JXFS_S_SHUTDOWN The device service has completed its shutdown and
is not usable any more.
JXFS_S_REMOTEFAILURE The communication between DS and DC is broken;
device is not accessible any more.
JXFS_S_POWERSAVEON Device is gone into power save mode.
JXFS_S_POWERSAVEOFF Device has returned from power save mode.
To make an application ready for receiving events of a specific type, it must implement the
corresponding listener interface by defining the included listener method.
All events have applicable event data attached to them and can be explicitly requested by
the application by using the addXXXListener Methods in the Device Control classes
(where XXX depicts the EventType). An application registering for 2 event types would
look like this (the try-catch expressions are not included):
public class Sample implements StatusListener,
Page 49
CWA 13937-1:2000
OperationCompleteListener
{
public Sample()
{
JxfsDeviceManager mgr=JxfsDeviceManager.getReference();
JxfsMagStripe mag=mgr.getDevice(myMagStripe);
mag.addOperationCompleteListener((OperationCompleteListener)this);
mag.addStatusListener((StatusListener)this);
...
}
public void operationCompleteOccurred(OperationCompleteEvent e)
{
if(e.getResult()==JxfsConst.JXFS_RC_SUCCESSFUL)
{
...
}
...
}
public void statusOccurred(StatusEvent e)
{
...
}
} // Sample.java
The OperationCompleteEvent received in the above method will be the receipt of the
requested operation for the application. It is received only by this application.
In contrast to that, the StatusEvent will be sent to any application which has a valid Device
Control.
The events generated in the Device Service are delivered to the control in a different thread
context. The Device Control has to catch them and store them in a event queue; returning
quickly to the Device Service. In another thread (one per event type) it now starts to
deliver the events to the application. It uses only a single thread to do it. Thus flow control
is simplified for the application. For details see "Threads and flow control"on page 14.
Any exceptions from the Device Communication layer (i.e. RemoteException) are logged
and a new JxfsException with error code JXFS_E_REMOTE is generated.
The Device Service gets references to objects which implement the following
IJxfsEventNotification interface. In these objects the corresponding fireXXXEvent
methods are invoked to deliver the events.
In cases where the event could not be delivered a JxfsException is thrown.
/////////////////////////////////////////////////////////////////////
//
// IJxfsEventNotification
//
// Interface defining callback methods in the Device
// Control that are callable by a Device Service.
//
/////////////////////////////////////////////////////////////////////
package events;
Now, what about the different subtypes of the OperationCompleteEvent and the rules
governing their use?
They are all found in the events package, together with their listeners. All sub-events have
their own Listener method in the application. This means, that if the application registers to
Page 50
CWA 13937-1:2000
receive e.g. OCMSDTrackReadEvents it gets these events in the corresponding listener
method. The event is NOT sent to the OperationComplete listener method, because all
events are only sent once to each application.
The OC events are generated in the Device Service, which uses the
fireOperationCompleteEvent() method to deliver it to the Device Control. As explained
earlier in detail in Threads and flow control on page 14, the Device Control has two queues
where it stores events for delivery to the application. One is used for StatusEvents, the
other for OperationComplete (or its subclasses) and Intermediate events.
The separate thread in the Device Control which has the duty to deliver all the OC events
to the registered listeners of this control now takes the topmost event from the queue and
must analyze its class. If it is one of the subclasses of the OperationCompleteEvent then
the corresponding listener method is invoked, if it is an original OperationCompleteEvent
it is sent to the OperationCompleteOccurred() method of the application.
Page 51
CWA 13937-1:2000
5 Support Classes
The following section discusses the number of additional classes provided to generally
support the defined infrastructure of J/XFS. These are both internal classes not visible to
the application or applet as well as support classes which are used to present data to the
application.
As this is a DM internal interface which is neither used by the application nor the controls
and services it is not within the scope of this standard to define the exact interface; this is
rather hidden in each specific DM implementation.
The important point is that two different kinds of server tasks are needed by the J/XFS
infrastructure; one for the static configuration and one for dynamic availability
information.
The question, how the information is loaded into the repository and how it can be changed
there is not generically solvable and thus not explained here. The forum is aware of the fact
that initializing, loading and administering the repository is a key feature of any program
implementing J/XFS.
Page 52
CWA 13937-1:2000
5.2 JxfsDeviceInformation
The basic configuration data describing the device is stored in the JxfsDeviceInformation
object or in its subclasses JxfsLocalDeviceInformation and JxfsRemoteDeviceInformation.
The objects of this classes are a kind of information container hiding configuration
structure from the Controls and Services layer; the means how this information is stored /
gathered can be changed by different implementations without affecting Device Service
and Device Controls.
They can query these objects for generic information about the control like its name, a
description of the device etc.
Currently the following standard properties (all read-only) are defined in the
JxfsDeviceInformation:
localDeviceName
The unique device name for this device in this J/XFS client. It is freely assignable during
the installation.
Note that this is a LOGICAL device name. Every device on a workstation must have a
unique name, even it is of the same type as another device!
deviceName
Page 53
CWA 13937-1:2000
This property only exists by its getDeviceName() method. It returns the localDeviceName,
but in the case of a remote device this name is augmented by the workstation name the
device is connected to. Although an implementation of J/XFS may want to use its own
format for the unique identification of a device we strongly suggest to use the format
<devicename>@<hostname>, i.e. [email protected] to specify
this. Please also see chapter Remote device access on Page 39 on this subject.
description
A String with the clear text description what this device is and where it can be found. May
be used to present in a list to the user. Sample: Passbookprinter 2nd floor (Mr. Millers
office).
deviceKey
Unique identifier for the device in the repository, e.g. the deviceName without blanks. This
is used to have a separation between the free-format device name and an identifier for the
repository which possibly poses certain restrictions to the allowed characters for keys. As
the localDeviceName this must be unique for all devices connected to a workstation.
The three DeviceInformation classes must implement Serializable as they are retrieved
from the repository and thus must be streamable over the network.
Almost every Device Service has a need to store some additional device specific
configuration data. This must also be put into the repository. As each Device Service has a
reference to its local configuration data this object also supports reading / writing of
arbitrary data.
The following methods are used for this:
Serializable getValueForKey(String key) throws JxfsException
This method allows an arbitrary persistent object to be retrieved under the given key into
the repository.
If the key is not found in the repository an exception with JXFS_E_NOEXIST is thrown.
void setValueForKey(String key, Serializable value) throws JxfsException
Saves the persistent object under the given name. If the key does not exist, it is created, if
it exists, the value is replaced. The object must be a subclass of Serializable.
To remove a key from the repository, use this method and specify null as the value
parameter.
An exception JXFS_E_ILLEGAL is thrown if the key specified is not allowed. This can
e.g. happen if the key contains invalid characters or if a read-only key with the same name
exists which cannot be overwritten
Also, there is a provision so that the Device Service can register itself here to be informed
if one of its key entries is changed on the server. It needs to implement the
IJxfsKeyValueChangeListener interface as described in the chapter on the
JxfsDeviceManager and use the following method of a LocalDeviceInformation object to
register:
void addKeyValueChangeListener(IJxfsKeyValueChangeListener listener, String
key) throws JxfsException
This method registers the listener to be informed when the value for the key "key" in the
repository changes. Throws an JXFS_E_PARAMETER_INVALID exception if one of the
parameters is null.
void removeKeyValueChangeListener(IJxfsKeyValueChangeListener listener)
throws JxfsException
Page 54
CWA 13937-1:2000
Removes the given listener. Throws an JXFS_E_PARAMETER_INVALID exception if
one of the parameters is null. If the listener is not known, an JXFS_E_FAILURE is thrown.
For the special case of querying the firmware level of the device, each DeviceInformation
object also provides the following methods:
JxfsVersion getFirmwareVersion();
This method can be used to gather the version information of a new firmware present
in the repository for this device. It is null if no new firmware is present.
byte[] getFirmware() throws JxfsException;
This call returns the actual byte codes of the firmware from the repository. It can be
used by the Device Service to update the device if requested..
The advantage of providing these special methods versus a generic getValueForKey()
access is that the same keys are used by all vendors to access the firmware.
5.3.1 Overview
Tracing
Tracing is used to track the running of the various components: To do this, trace points are
implemented in the programs. When they are activated they provide the logger object with
information about internal states and events.
The trace points can be defined in different levels (trace point for function entry and
function exit, trace point for tracing configuration entries, trace point for tracing debugging
information, etc.). The activation of the different trace points can be component specific
during runtime, e.g. if a developer is interested in the function entry and function exit
points only, he has to activate the appropriate trace point for this specific component. This
mechanism to activate different trace points during runtime is defined by the logger object.
The trace is therefore primarily a mechanism to analyze the behavior of the application or
software modules and is mainly used by developers or field engineers.
A sufficient number of trace points can be set for every component; each of these points
being unique in the system. Every trace point can be activated externally and without the
relevant module being involved.
Error logging
In contrast to traces, error logging is used for the continuous logging of error or warning
events from the components. Error logging is always active. Whenever a component calls
the logger object's method to do error logging, an error log entry is produced by the logger
object.
When collecting and recording trace and error data the standard logger object separates the
two types of data from one another so that subsequent components which are, for example,
only interested in error data, do not have to filter a mass of trace entries to isolate this error
data. Via additional software modules these collected errors may be transferred to a central
system (i.e. SNMP Event Reporting, see below).
This error logging facility serves as the central point where error information from the
devices is gathered. It is therefore important that all devices make extensive use of this
facility.
In the graphic below we have a small scenario of which messages and events would be
triggered by a hardware error. It also shows how a service application might register for the
Device and query its status after an error has occurred. Please note that the textual strings
are in a language-specific format. Every DS has the duty to create this form of the
information. In order to allow for a multi-language installation the DS can use the
Page 55
CWA 13937-1:2000
getTextResource() utility function from the JxfsLocalDeviceInformation object to receive
the textual representation of an error. See JxfsDeviceInformation on page 52 for further
details.
Service
Application
Customer
Application (6) myDevice.getStatus() (4a) StatusEvent Monitoring
JXFS_S_HARDWAREERROR
Application
(5a) OperationCompleteEvent (7a)
JXFS_E_HARDWAREERROR
(1) myDevice.operation()
DeviceControl
errorLogOccurred(
DeviceControl (3b) JXFS_E_HARDWAREERROR,1234,
V.24 Timeout, Check connection
5.3.2 JxfsLogger
The JxfsLogger is a single separate object which exists in every Java VM. Every object of
course has access to its local JxfsLogger only. It can report errors and write informational
and trace messages to the log.
The final logging of all messages is not done by the JxfsLogger itself. Rather a listener
interface exists which can be implemented by other objects (under application control).
The JxfsLogger sends out the messages to any object which has registered to be a listener.
This is a very flexible mechanism using the Java event notification scheme, which makes it
easy to distribute the available information.
There is also no restriction on who is using the JxfsLogger. It is especially not restricted to
transfer only J/XFS related messages. Basically, even the application might use the
JxfsLogger to report whats going on to an independent instance.
Object x An ErrorLogListener
JxfsLogger
A DC A LogListener
ErrorMsgs
A DS LogMsgs An ErrorLogListener
The objects (or module groups of objects) which want to send messages to the JxfsLogger
must first initialize the JxfsLogger for their use. They have to send it a short textual
identifier and a longer description suitable for display. The short identifier must be used for
all subsequent write calls. This is used by the JxfsLogger and its listeners to identify which
class or module has generated the message and also enables them to use filters on a module
bases.
Then they can use the 2 different writing methods, one for reporting error conditions and
the other one to write trace log entries. The log entries are delivered with a level indicator
which can be analyzed by a LogListener.
The ErrorLogListener interface servers for instances which are only interested in the error
messages which are reported. It is defined like this:
/**
* IJxfsErrorLogListener.java
*/
public interface IJxfsErrorLogListener
{
public boolean initialize(String parameters);
public void errorLogOccurred(String source_identification,
String origin,
long errorCode,
long extendedErrorCode,
String message,
String hintText,
String help_url,
String curr_thread,
Date timestamp);
public void shutdown();
public String getDescription();
}
The first method is used to initialize the object. This is needed to have an initialization
mechanism independent of the specific implementation.
The errorLogOccurred method is called by the JxfsLogger for every error message which
is reported. The parameters in the errorLogOccurred method are explained below in the
writeErrorLog method of the Logger, with the only difference, that the first parameter here
is a stringized representation of the originating object.
The shutdown method is called by the JxfsLogger to inform the registered logger that after
this method the system will shut down. This call must always return and allows the logger
to do some cleanup work.
And finally, the getDescription() method should return a short (max. 80 chararcters)
human-readable description of this LogListener, e.g. "FileLogger logging to c:\logfile". In
multi-language environments this String should be internationalized.
Page 57
CWA 13937-1:2000
A LogListener interface is also provided which also contains the error interface but
augments it by supplying the log messages, too.
/**
* IJxfsLogListener.java
*/
public interface IJxfsLogListener extends IJxfsErrorLogListener
{
public void logOccurred(String source_identification,
String origin,
int level,
String log_message,
String curr_thread,
Date timestamp);
} // LogListener
As can be seen in above interface description, the idea is that LogListener inherit from the
ErrorLogListener, i.e. they are receiving both error and normal logging messages. The
ErrorLogListener only receive the error messages.
JxfsId
In order to provide information about a registered Logger, a helper class JxfsId is defined,
which only contains information about a LogListener. It contains a description (as returned
by the corresponding LogListener) as well as an integer id which is set to a unique value
from the JxfsLogger in order to clearly identify this LogListener.
Remark: This class may also be used to identify objects in other occasions, as its definition
is quite generically applicable. The only prerequisite is that an integer is sufficient to
uniquely identify the instance and a string-based description is available.
JxfsId has the following methods:
JxfsId(); // the constructor
JxfsId(int id, String description); // second constructor
void setId(int id); // Setter for id
int getId(); // Getter for id
void setDescription(String description); // Setter for description
String getDescription(); // Getter for description
String toString(); // returns the id + the description in one String
Object clone(); // returns a clone of this object
Now, the main class JxfsLogger has the following public methods:
static JxfsLogger getReference()
Returns the reference to the JxfsLogger-Object. Must be used to access this singleton.
boolean registerModule(String origin, String description)
Must be used by each object before the first line is reported to identify itself in both a
short and a long form. The short form should uniquely identify this object (i.e.
DevMgr), and the description should be suitable for display in a supervisor
application, e.g. Acme Passbook printer Device Service, Version 1.2)
This method returns false if the given origin already exists as registered.
boolean deregisterModule(String origin)
If the object doesnt use the Logger any more it should deregister using this call. If
should only do this if it has successfully registered before.
This method returns false if the origin wasnt found in the registered list.
boolean writeErrorLog(Object issuer,
String origin,
long errorCode,
long extendedErrorCode,
String message,
String hintText,
String help_url)
Use this method to issue an error message. The issuer is the sending object itself. The
origin is a short string with the module identification, it should have been announced
to the logger by a previous registerModule() call.
The errorCode is the generic errorCode for this error, extendedErrorCode is a device
specific, more detailed, code. The message is the error message itself in a language-
specific form, the hintText gives some hints regarding a way to solve the error. Both
message and hintText should not be long explanations but rather short strings (1-3
lines), and the help_url gives the originator of the message a way to announce where
more detailed information regarding this error can be found.
Page 58
CWA 13937-1:2000
extendedErrorCode may be specified as 0, hintText and help_url may be left blank
() if they are not applicable. The other parameters are mandatory.
False is returned if some internal error occurred.
To use an unregistered origin here is not recommended, but the message is logged
anyway.
boolean writeLog(Object issuer, String origin, int level, String message)
Use this method to issue a log message. The issuer is the sending object itself. The
origin is a short string with the module identification, it should have been announced
to the logger by a previous registerModule() call.
The level identifier is an integer. It is left to the programmer to define the exact
semantics of this integer.
The message itself should be clearly readable, and may also be language specific using
the mechanism as outlined in the writeErrorLog method description.
To use an unregistered origin here is not recommended, but the message is logged
anyway.
boolean isLogActive(String origin, int level)
If logging is used there are potentially very many log entries. It is advisable to prevent
generation of many log messages which are only thrown away afterwards. Also,
creating the message to be logged may be time-consuming. For maximum system
performance, before issuing a writeLog() call the issuer can check if that message
should be logged at all. It does so by calling this method. If True is returned, the
logging is desired. So, a typical usage is
if (JxfsLogger.getReference().isLogActive(DM,5)
{
JxfsLogger.getReference().writeLog(DM,5,0,
Cannot load class+classToInstantiate,,);
}
The logActive state may dynamically change during runtime. A user of the logger
should not issue this only once during startup but before every call.
How is this logging activated and deactivated? This is considered to be a detail of a
J/XFS implementation and is thus not described here.
JxfsId addErrorLogListener(IJxfsErrorLogListener listener) ,
JxfsId addLogListener(IJxfsLogListener listener)
Any object implementing the required interfaces can register with these methods to
receive either only the error messages or both error and log messages. Any registered
LogListener will also receive all error messages.
A registration of the same object to both methods returns an error.
If the listener could not be added, a null value is returned.
boolean removeErrorLogListener(int listenerId) ,
boolean removeLogListener(int listenerId)
Use this method to deregister interest in the messages. The parameter can be queried
from the JxfsId object corresponding to this Listener (returned from the following
method)
Vector getErrorLogListeners()
Return a Vector containing objects of type JxfsId for all registered ErrorLogListeners.
Vector getLogListeners()
Return a Vector containing objects of type JxfsId for all registered LogListeners.
IJxfsErrorLogListener getErrorLogListener(int listenerId)
Return the reference to the ErrorLogListener identified by the listenerId.
IJxfsLogListener getLogListener(int listenerId)
Return the reference to the LogListener identified by the listenerId.
As stated above, the level integer specified in the trace log messages is not predefined.
This standard, however, proposes to adhere to the following rules:
Ids from 1 to 9 should be used to describe the workflow as outlined below;
Page 59
CWA 13937-1:2000
Ids 10 to 99 are for generic trace points
Ids starting with 100 are for additional custom trace points.
Value Meaning
1 Report with this id that an operation request was made and interesting
parameters to it.
2 Report with this id if an operation was completed, i.e. an OC Event is sent and
its values.
3 A device property has changed.
4 The device status has changed (includes device ready, device closed and
shutdown).
10 Method entry
11 Method exit
J/XFS contains a generic logger to which arbitrary listening objects can register. This can
be any specific logger objects (e.g. a Tivoli SNMP client object) or even the application
itself. It can be expected that when the J/XFS device framework spreads, the systems
management vendors will implement respective loggers for their infrastructure. Any
program implementing the J/XFS infrastructure should usually also provide for a set of
simple LogListeners.
/////////////////////////////////////////////////////////////////////
// Return Codes from calls which deliver an immediate result
/////////////////////////////////////////////////////////////////////
/**Standard return for successful calls*/
public static final int JXFS_RC_SUCCESSFUL = 0;
/**Unspecified unsuccessful return */
public static final int JXFS_RC_UNSUCCESSFUL = 1;
/////////////////////////////////////////////////////////////////////
// Exception codes
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// Status Constants
/////////////////////////////////////////////////////////////////////
public static final int JXFS_S_RELEASED = 1;
public static final int JXFS_S_CLAIMED = 2;
public static final int JXFS_S_HARDWAREERROR = 3;
public static final int JXFS_S_USERACTIONERROR = 4;
public static final int JXFS_S_WORKING = 5;
/* Inform or a shutdown */
public static final int JXFS_S_SHUTDOWN = 6;
public static final int JXFS_S_POWERSAVEON = 7;
public static final int JXFS_S_POWERSAVEOFF = 8;
/* Additional DeviceManager stati */
public static final int JXFS_S_SERVICE_STOPPED = 9;
public static final int JXFS_S_SERVICE_STARTED = 10;
public static final int JXFS_S_REMOTEFAILURE = 11;
/* Status changes */
public static final int JXFS_S_BIN_STATUS = 12;
public static final int JXFS_S_MEDIA_STATUS = 13;
/////////////////////////////////////////////////////////////////////
// General Constants
/////////////////////////////////////////////////////////////////////
public static final int JXFS_FOREVER = -1;
public static final int JXFS_ALL = -1;
}
5.5.1 JxfsType
extends Object implements Serializable
This is a class any J/XFS class which contains data should inherit from. This can be the
data objects delivered within some events or any other complex object which serves as an
input or output parameter for Device Control methods.
This is needed to ensure the streamability of any data class used in J/XFS because any data
object might be streamed over a network connection and must be stored in the repository in
its binary format.
Java base data types like String, int, etc. are streamable anyway and thus may be used as
parameters without putting them into special wrapper classes.
A common question arising here is: Why does JxfsType not implement Cloneable (and
overriding method clone()) to ensure that any data class can be cloned, and why does it not
specify toString(), hashCode() and equals() as abstract methods? This would force any data
class to implement these methods.
This is intentionally not specified here because all these features are not generally required,
and it is left to the specific subclass to override these methods or not.
In the following chapters a number of generic data classes are defined. They can be used as
base classes for device specific extensions or right away as return values for device
specific things.
Page 62
CWA 13937-1:2000
5.5.2 JxfsStatus
The JxfsStatus object delivers status information for J/XFS.
Each Device Service has such an object. A copy of this is returned from the getStatus()
method.
The contents of this object reflects the DeviceService status at the time when the object
was returned.
The object returned is at least of type JxfsStatus, and may be a subclass of it. Each device
type which has additional status makes a subclass of it and adds the corresponding set and
query methods to this object. A sample could be e.g. JxfsPrinterStatus. It is always only
filled by the Device Service.
The device type specific subclasses extend this base object by adding properties and the
corresponding is... and set... methods.
These status objects report the complete status of a device. Some device types possibly
have other objects to report special subtypes of status (two standard ones mentioned below
are JxfsMediaStatus and JxfsBinStatus for the number of bins present in a device). They
are usually contained within the general Status object and queried via special methods.
Page 63
CWA 13937-1:2000
To get information about the fill level of the retain bin in a motorized MSD the application
has to issue the following calls:
JxfsBinStatus retain=myMSD.getStatus().getRetainBinStatus();
if (retain.isFull()) ....
This relationship of JxfsStatus, its subclasses and their aggregates is outlined in the
following graphic:
5.5.3 JxfsMediaStatus
This class defines a generic API to query the status of a media in a device. It is e.g. used by
the printer to represent its paper position or by the motorized MagStripe device class to
represent the card location.
This object is received by the application either by calling getStatus() and querying the
device specific status object9 or by analyzing the details object in the StatusEvent.
The state given by the JxfsMediaStatus object reflects the state of the device at the time of
its sending, i.e. the device state may already have changed again. It is always only filled by
the Device Service.
If the application wants to check if the mediaState checking is supported a method inside
the containing JxfsStatus or the device capabilities must be queried.
Summary
Implements : Cloneable Extends : JxfsType
9
The method call would be similar to myPrinterDeviceControl.getStatus().getPaperPosition(). See section
JxfsStatus for explanation.
Page 64
CWA 13937-1:2000
isEjected boolean Media is in the entry/exit slot of
the device.
isJammed boolean Media is jammed in the device.
isPresent boolean Media is inserted in the device.
isUnknown boolean State of the media cannot be
determined with the device in its
current state.
toString String Returns a short textual
representation of the contents of
this object.
Properties
mediaState Property R
Type int
Initial Value JXFS_S_MEDIA_UNKNOWN
Description Specifies the current state of the media. Depending on device capability,
mediaState will be set to one of the following values:
Value Meaning
JXFS_S_MEDIA_EJECTED=1 Media is in the entry/exit slot of the
device.
JXFS_S_MEDIA_JAMMED=2 Media is jammed in the device.
JXFS_S_MEDIA_PRESENT=4 Media is inserted in the device.
JXFS_S_MEDIA_UNKNOWN=8 State of the media cannot be
determined with the device in its
current state.
Event If the value of this property changes, the Device Service will send all
registered StatusListeners a StatusEvent with the following value and the
corresponding mediaState object. This usually overrides the generation of a
generic UserActionError event.
Value Meaning
JXFS_S_MEDIA_STATUS mediaState changed.
The setting of the property should only be done by the respective device service (using the
setMediaState() method).
Methods
Rather than analysing the mediaState integer, the application should use the following
methods query the status. As the contents of the queried status object does not change after
it has been received they are always available and do always return the same value. They
also do not generate any events or take any parameters.
isEjected Method
isJammed Method
isPresent Method
isUnknown Method
toString Method
5.5.4 JxfsThresholdStatus
This class defines a generic API to query and detect several threshold values. This can be
e.g. the paper supply present in a printer (to detect if its low or empty) or the retain bin of
a card reader (to detect if its full or almost full).
This object is received by the application either by calling getStatus() and querying the
device specific status object or via certain StatusEvents. The state given by an object of
this type reflects the state of the device at the time of its sending, i.e. the state may already
have changed again. It is always only filled by the Device Service.
If the application wants to check if the threshold checking is supported a method inside the
applicable JxfsStatus or the device capabilities must be queried.
Summary
Implements : Cloneable Extends : JxfsType
Properties
thresholdState Property RW
Type int
Initial Value n/a
Description Specifies the status of the threshold. Depending on device capability,
thresholdState will be set to one of the following values:
Page 66
CWA 13937-1:2000
Value Meaning
JXFS_S_BIN_OK=0 Bin is O.K.
JXFS_S_BIN_FULL=1 Bin is full.
JXFS_S_BIN_HIGH=2 Bin is high.
JXFS_S_BIN_LOW=4 Bin is low.
JXFS_S_BIN_EMPTY=8 Bin is empty.
JXFS_S_BIN_UNKNOWN=16 State of the bin cannot be determined
with the device in its current state.
Event If the value of this property changes, the Device Service will send all
registered StatusListeners a StatusEvent with the following value and the
corresponding JxfsThresholdStatus object. This usually overrides the
generation of a generic UserActionError event.
Value Meaning
JXFS_S_BIN_STATUS thresholdStatus changed.
The setting of the property should only be done by the respective device service (using the
setThresholdState() method).
Methods
isFull Method
isHigh Method
isLow Method
isEmpty Method
isUnknown Method
J/XFS does provide only a basic access methods to such data as it is felt that this is
sufficient for J/XFS needs. This means that the following features are NOT found in the
J/XFS repository access interface:
Elaborate, transaction-based access and rollback mechanisms.
Mechanisms to enumerate and cycle through key sets.
Temporary data storage (this can be done by each DS itself). The persistent data store
offered here really writes any keys persistently to a disk.
Each Device Control and Device Service as well as the JxfsDeviceManager has a method
to return its version. This is returned via a JxfsVersion object (see below).
In addition to the version numbers some description calls must be implemented, which
return a string giving a description and copyright. The control layer collects these
properties during startup, e.g. ACME Magnetic Stripe Reader Device Service 1.03
(c)1999 Acme corp.
If a class is loaded, its version number can be checked by the calling class through
getXXXVersion() calls against its own version. Generally, to be usable, the major numbers
must match, but the minor number may be different. It is the duty of the calling class
Page 68
CWA 13937-1:2000
(either a Device Control or the Device Manager) to decide whether or not the class is
usable.
Build numbers should be incremented for Bugfixes and minor changes and should not be
needed for decision purposes.
Every time the J/XFS standard is extended by addition of methods to device control
interfaces and device service interfaces, device controls and device services must
implement these new methods to be usable with kernel implementations of the new
standard.
Old services, which do not implement these methods are not usable with new kernel
versions until the vendor of the service provides an up-to-date service implementation. To
bridge this time gap between new kernel release and updated service release, kernel
implementations offer abstract service classes for each device type which can be extended
by device service implementations. These abstract base classes implement their
corresponding device service interfaces and their implementation of new methods throw
JxfsException with error code JXFS_E_NOT_SUPPORTED.
Old device service implementations extending these abstract classes inherit the new
methods and can so continued to be used with new kernels. Once the vendor provides the
new functionality in updated device service implementations, the service classes override
the inherited methods and perform their intended function instead of throwing
JxfsException with error code JXFS_E_NOT_SUPPORTED.
Java VM
Instance of
DeviceServiceA J/XFS
Applicatation
instanceof class file
(user)
DeviceServiceA
J/XFS kernel extends
(J/XFS forum)
Abstract class
DeviceServiceA
implements
Interface for
DeviceServiceA
DeviceServiceA
class file
(device vendor)
JxfsVersion
The .JxfsVersion object delivers version information for J/XFS. It also contains a
description of the generating object. Each Device Control and Device Service has such an
object which is returned in the getDeviceControlVersion() and getDeviceServiceVersion()
methods. The (only) constructor for this class is JxfsVersion(int vendorMajor, int
vendorMinor, int vendorBuild, int jxfsMajor, int jxfsMinor, String description).
Usually, this is a static object within each class which needs to deliver versioning
information of itself.
Additionally, the following methods can be used to query the object:
Page 69
CWA 13937-1:2000
public int getVendorMajor()
Return the major release number of the vendors implementation.
public int getVendorMinor()
Return the minor release number of the vendors implementation.
public int getVendorBuild()
Return the build number of the vendors implementation.
public int getJxfsMajor()
Return the major release number of the implemented J/XFS standard.
public int getJxfsMinor()
Return the minor release number of the implemented J/XFS standard.
public String getDescription()
Return a more detailed description about this object which should also be suitable to
be printed out. So, the format should be similar to ACME Magnetic Stripe Reader
Device Service 1.03 (c)1999 Acme corp.