The library is OSI Certified Open Source Software, and a copy of the license terms can be found here.
com.ascert.comms.x25
- contains a standard set of interfaces which applications use to access and communicate using X.25. In general, the user application can be coded against these interfaces and work with any specific X.25 card vendor's implementation.
com.ascert.comms.drivers.*
- contains implementations of the X.25 API classes for various vendor's X.25 cards and software drivers.
It will be advantageous to developers using this library to have at least a basic familiarity with X.25. A handy summary of various technical aspects such as packet formats, facility codes etc. is included here, reproduced by kind permission of it's author, Les Thompson (the original may be found here).
The library is supplied with driver implementations for the FarSite Communications Ltd range of X.25 cards. Note that to use these, in addition to an installed X.25 card and driver software, you must also install the Sockets API which should have been supplied with your card.
cd examples javac -classpath ..\lib\x25.jar Test1.java
Some *very* basic example programs have been included showing basic usage of the various API methods. These were created and used during the initial development and testing of the library.
In the simplest case, you will be using the standard system classloader, which uses a property to locate library paths e.g.
java -cp lib\x25.jar;examples -Djava.library.path=lib Test1
Batch scripts are provided to compile and run the example programs:
These can be run by typing the batch script name, followed by the example program number e.g.
gotest 1
Note, however, that some Java environments (e.g. J2EE, OSGi etc.) use custom classloaders that have different strategies for locating classes and native libraries. In these cases it will be necessary to ensure that the JAR file and native libraries are installed in appropriate directories, and the necessary configuration options are set to ensure correct loading.
Further information on the native libraries provided, can be found in the vendor specific driver class documentation:
Developer's create an X25SocketFactory
instance, which is then used to construct and configure X25Socket
objects to perform X.25 communications. The following code snippet is an example of this:
The... // create an X.25 socket X25SocketFactory = new X25SocketFactory(null); X25Socket sock = factory.getSocket(); ... IOException should be caught and handled...
X25SocketFactory
can take an optional implementation class in it's constructor, which will force the factory to use a specific driver implementation. Typically though, a developer will want to leave this for selection at runtime to allow their applications to work with any implementation. If no implementation class is provided the default factory will be used, which can be specified by setting the System property com.ascert.comms.driver.farsite.X25FactoryImpl
to the fully qualified classname of the X25Factory
implementation class.
connect
), or wait for calls from a remote party (accept
). On a single socket these operations are mutually exclusive, although an application can create multiple sockets, some of which make outgoing calls, and some of which receive incoming calls.
Outgoing calls can be made as follows:
Incoming calls can be received as follows:... // create socket to make a call to NUA 23420000222201 X25Socket sock = factory.getClientSocket("23420000222201"); ...sock
is connected and can be used for data transfer... ... IOException should be caught and handled...
Both the examples use 'convenience' methods for creating client and server sockets with typical settings. For more detailed control, unconfigured sockets can be created using... // create socket to accept calls to NUA 23420000222201 X25Socket srv = factory.getServerSocket("23420000222201"); X25Socket sock = srv.accept(); ...sock
is connected and can be used for data transfer... ...srv
can now be used to accept further calls... ... IOException should be caught and handled... ...
getSocket
and then configured manually using the X25Socket
interface.
send
and receive
operations. Rather than just sending and receiving byte buffers, an X25Message
object is used, allowing access to and control of both the message buffer, and message status indicators such as the M-bit and Q-bit.
A simple example of sending data is as follows:
A simple example of receiving data is as follows:... String txt = "+++ This is my message to you +++"; X25Message msg = new X25Message(txt.getBytes()); sock.send(msg); ... IOException should be caught and handled... ...
Note that... X25Message msg = new X25Message(new byte[bufsz]); if (sock.recv(msg) > 0) { //got some data, process it. String txt = new String(msg.getMsg(), 0, msg.getLen()); System.out.println("Recv: " + txt); } else { //socket disconnected, close it } ... IOException should be caught and handled... ...
send
and recv
operations are blocking, as with the standard TCP socket calls. Multiple threads can be used to support concurrent sending and receiving of data.
shutdown
or close
operation. In general, shutdown
is a more 'graceful' operation, although in practice many driver implementations may treat these two as synonymous since X.25 does not strictly have a definition of a 'graceful' shutdown.
An example of closing a connection is as follows:
Regardless of which method is used, applications should take care to close all sockets used, including server sockets prior to termination to ensure that resources are freed. One method to detect abnormal terminations and perform cleanup is to register shutdown threads using... sock.shutdown() ... IOException should be caught and handled... ...
Runtime.addShutdownHook()
. This is an inifintely preferably cleanup approach than using finalizers, which are not guaranteed to run on all exit scenarios, and which can seriously hamper the garbage collector if they contain possibly long running operations.
Source code to all compiled components is also included should the user need to re-build from sources. The pre-requisites for building from source are as follows:
It's quite possible to use other build tools, and other C compilers. But the above are freely available, powerful, target multiple platforms, widely used, and are well supported.
Important note for Windows users:
There is one small change which is needed to the Java JNI header files when compiling under Windows. The include\win32\jni_md.h
file needs to be modified as follows:
This is because/*typedef __int64 jlong;*/ #ifdef __GNUC__ typedef long long jlong; #else typedef __int64 jlong; #endif
__int64
is not a supported data type under GCC.
/build/build.xml
. This contains the following top level build targets:
build_win32
- to compile the Java classes, and build the native libraries for Windows.
build_linux
- to compile the Java classes, and build the native libraries for Linux.
javadoc
- create the javadoc documentation.
clean
- to cleanup all compiled and built output files.
For example, to build the library for Linux:
Note: without some serious GCC configuration steps to support cross compilation, build targets must be performed on the target OS to which they apply.cd build ant build_linux ...lot's of output, with hopefully a BUILD SUCCESSFUL at the end...