The XPortal API defines a platform-independent "packetizing" protocol to map between the stream based semantics of TCP/IP and the packet based semantics of X.25. The API is defined in the C Language include file pxsx25def.h as a group of types and macros for encoding and decoding packets sent to and from xportal server running on the PXS.
All packets transferred over TCP/IP between client and server begin with a 2-byte length field in network byte order (most significant byte first). The receiver decodes this field to determine how much additional data follows.
Typically, the client will send an initial packet indicating the kind of
X.25 service required, either an SVC or, if a PVC, the logical channel number
(LCN). (If the service is an SVC, the client may optionally specify the call request
data (address and facilities) to be used in the X.25 Call Request packet.)
The format of this initial request is defined by the PxsX25RequestStruct
type. Macros for encoding and decoding these requests are provided. For
instance, to encode a request for a PVC on LCN 23, the client would do:
#include "pxsx25def.h" PxsRequestStruct request; int length; pxs_ENCODE_PVC_REQUEST(&request, 23, length); /* Send length bytes to the server */ send(sock, &request, length, 0);
To encode a request for an SVC with 17 bytes of call data stored in the array
data
, the client would do:
#include "pxsx25def.h" PxsRequestStruct request; int length; pxs_ENCODE_SVC_REQUEST(&request, 17, data, length); /* Send length bytes to the server */ send(sock, &request, length, 0);
Any call request data included in the request must be correctly encoded as it will be sent as is in the body of the X.25 Call Request packet. It is recommended that clients use the LayGO X.25 Call Setup API to insure proper encoding.
If the request can be honored, (the PVC requested is available or there is an available SVC), the server initiates X.25 connection setup and, once completed, begins transferring data back and forth between TCP/IP and the X.25 virtual circuit. If the request cannot be honored or if X.25 connection setup fails, the server simply closes the TCP/IP socket.
To send and
receive data, the client can use the PxsDataStruct
type. The data to be
sent is copied into the data
field of the structure, then the total
packet length is encoded into the length
field. For instance, to send 98 bytes of data, the client would do:
PxsDataStruct packet; int length = 98; memcpy(packet.data, data, length); pxs_SET_DATA_LENGTH(&packet, length); /* Send length bytes to the server */ send(sock, &packet, length, 0);
To receive a packet from the server, the client would do:
PxsDataStruct packet; int length; /* Receive 2 bytes into &packet.length */ recv(sock, &packet.length, 2, 0); pxs_GET_DATA_LENGTH(&packet, length); /* Receive length additional bytes into packet.data */ recv(sock, &packet.flags, length, 0);
After the second recv()
, the contents of the packet.flags
field contains status of the X.25 D-bit
, M-bit
and Q-bit
the
packet was received with:
if (packet.flags & pxs_FLAG_D_BIT) { /* the D-bit is set */ } if (packet.flags & pxs_FLAG_M_BIT) { /* the M-bit is set */ } if (packet.flags & pxs_FLAG_Q_BIT) { /* the Q-bit is set */ }
The packet.data
field will contain length - pxs_HEADER_SIZE
bytes of data from the packet.
To have xportal set the X.25 D-bit
, M-bit
and/or Q-bit
in a packet you
are sending, encode the packet using the pxs_SET_DATA_LENGTH_AND_FLAGS()
macro.
For instance, to send 37 bytes of data with the D-bit
and M-bit
clear and the Q-bit
set,
the client would do:
PxsDataStruct packet; int length = 37; memcpy(packet.data, data, length); pxs_SET_DATA_LENGTH_AND_FLAGS(&packet, length, !pxs_SET_D_BIT, !pxs_SET_M_BIT, pxs_SET_Q_BIT); /* Send length bytes to the server */ send(sock, &packet, length, 0);
Some X.25 M-bit
processing can be handled entirely by xportal.
For instance, if xportal is configured to accept up to 512 bytes
of data at a time from clients, but the X.25 maximum packet size is 128, it will
automatically use the X.25 M-bit
to fragment packets of up to 512 bytes in the TCP/IP
to X.25 direction and to assemble packets in the X.25 to TCP/IP direction. The
client application does not need to use the M-bit
. However, if the
total size of the packets exchanged is greater than xportal has
been configured to accept, the application will need to use and monitor the status of the
M-bit
. For instance, if xportal is
configured to accept up to 512 bytes of data, but the client
wants to send a 1K packet, the client should send xportal
1 512 byte packet with the M-bit
set and a second 512 byte packet
with the M-bit
clear. xportal will
handle any fragmentation below 512 bytes that is required. If xportal
receives a packet sequence of greater than 512 bytes over X.25, it will assemble them int blocks of
up to 512 bytes to send to the client and use the M-bit
.