HPlogo X25/9000: X.25/9000 Programmer's Guide > Chapter 4  Sending and Receiving Data

Data transmission requirements

» 

Technical documentation

Complete book in PDF

 » Table of Contents

 » Index

When an SVC has been connected, data can be sent and received over the SVC. The sending and receiving of data is identical for both sides of a con nection regardless of whether the role of client or server was played when the connection was made.

An application process can use send() and write() system calls to transmit data, and use recv() and read() system calls to receive data, on an SVC. Using read() and write() has the advantage of being part of the UNIX standard I/O package. They are also simple to use. Using send() and recv() offers greater flexibility and control of data transmission. They are the only calls that can be used for data in INTERRUPT packets.

The M bit versus the MDTF bit

Data is transmitted and received as messages or message fragments. A message contains one or more DATA packets. All packets are separated by an M bit ("More" bit), except for the last packet.

If the MDTF bit is not used with the ioctl(X25_SEND_TYPE) system call, all of the packets which have been sent by a single send() or write() system call are sent as a single message. That is, X.25 divides the send or write buffer into packets and sends them in order with the M bit set in all but the last packet.

If the MDTF bit is specified with the ioctl(X25_SEND_TYPE)system call, longer messages can be sent with a single send() or write() system call.

Unless the ioctl(X25_SET_FRAGMENT_SIZE) system call is used with the MDTF bit, messages must be received with a single recv() or read() system call. If the ioctl(X25_SET_FRAGMENT_SIZE) system call is used, the message may be read as a series of message fragments, which allows extremely long messages to be read.

The send(), recv(), read(), and write() calls can be mixed within a program.

Sending Data

The send(2) and write() calls can be used anytime after a connection has been established. The caller is blocked until the specified number of bytes have been queued to be sent, unless you are using nonblocking I/O. Nonblocking I/O is described later in this chapter.

If the number of bytes to be transmitted is greater than the packet size permits, the data will be transmitted in a series of packets with the M bit set automatically. If you need to send a message which is longer than a single send(2) or write(2) buffer, you can control the use of the M bit with ioctl(X25_SEND_TYPE).

The syntax for write() is fully described in your HP-UX man pages.

Syntax for send()

The syntax for the send() system call and its parameters are described below.

#include <sys/types.h>
#include <sys/socket.h>
int count;

int sd;
char *msg;
int len, flags;

count = send(sd, msg, len, flags);
sd

A socket descriptor for a connected SVC socket.

msg

A pointer to the buffer containing the data to be transmitted over the SVC. Although this is a character buffer, X.25 has no requirement that the data actually be ASCII characters. This is entirely up to the application.

len

The length of the msg buffer in bytes.

flags

Indicates the type of data and packet in which to send the data. If 0 is specified, then X.25 sends a DATA packet containing the data. If the out-of- band flag is set (OOB_MSG), then X.25 sends an INTERRUPT packet containing the data. For details on sending interrupt data, refer to Chapter 5 “ Receiving and Transmitting Out-of-Band Information”.

count

Is either -1 or the number of bytes actually sent. If count is -1, then errno contains the error code. If errno returned EINTR, a signal was received.

If a SIGURG signal is received during a send() call, the state of the VC may have changed. Design your program to check the state of the VC before attempting to send() data again after a SIGURG signal has arrived.

Refer to the send(2) entry in your HP-UX man pages for more on this.

Receiving Data

The recv(2) and read(2) calls can be issued any time after a connec tion has been established. The caller is blocked until there is a message available for reception, unless nonblocking I/O is in use. Nonblocking I/O is described later in this chapter.

If X.25 receives a series of packets with the M bit set, the packets must be read with a single system call, or as a series of message fragments. If the application is reading message fragments the ioctl(X25_SET_FRAGMENT_SIZE) must be set.

The syntax for read() is fully described in your HP-UX man pages.

Syntax for recv()

The syntax for the recv() system call and its parameters are described below.

#include <sys/types.h>
#include <sys/socket.h>
int count;

int sd;
char *buf;
int len, flags;

count = recv(sd, buf, len, flags);
sd

A socket descriptor for a connected SVC socket.

buf

A pointer to the buffer which will receive the data message. Although this is a character buffer, X.25 has no requirement that the data actually be ASCII characters. This is entirely up to the application.

len

The length of buf in bytes. If the message or message fragment available to be read is larger than the value specified in len, the remainder of the message or message fragment will be discarded. Once the data has been read it is discarded. The MSG_PEEK allows a message to be received without any data being discarded. The number of bytes to be read can be obtained with ioctl(X25_NEXT_MSG_STAT), described later in this chapter.

flags

Indicates the type of data to be read, and whether or not to discard the message after reception. If 0 is specified, then X.25 returns data transmitted in normal DATA packets. If the peek flag MSG_PEEK is set, the data is copied into the buffer, but not discarded afterwards. If the out-of-band flag is set (OOB_MSG), then the call never blocks and X.25 returns data from the out-of-band queue. If OOB_MSG is set and no out-of-band data is available, recv() returns 0. For details on receiving interrupt data, refer to Chapter 5 “ Receiving and Transmitting Out-of-Band Information”.

count

Either -1 or the number of bytes actually copied into buf. If count is -1, then errno contains the error code. If errno returned EINTR, a signal was received. Correct the cause of the error before attempting to recv() data again. If the out-of-band flag is set (OOB_MSG), then the call never blocks and X.25 returns data form the out-of-band queue.

Unless nonblocking I/O is being used, recv() blocks until a complete X.25 message arrives, a signal arrives (for example, SIGURG), or the VC is terminated. Nonblocking I/O is described later in this chapter.

Controlling the MDTF, D, and Q bits

The MDTF, D, and Q bits are used to indicate special usage of DATA pack ets. X.25 allows applications to control the use of these bits with ioctl(X25_SEND_TYPE).

When the M bit (more bit) is set in a DATA packet it indicates that the message requires one or more additional packets before it is completed. The M bit can be used automatically or under application control: all packets used to transmit a single send() or write() buffer are linked with the M bit.

When the D bit (Delivery Confirmation bit) is set in a DATA packet it requires that confirmation be sent upon its arrival at the remote DTE. To use the D bit in data transmission, the D bit must be set at connection time in the CALL REQUEST or CALL ACCEPTED packet.

The Q bit (Qualifier bit) is used to indicate a PAD CONTROL packet and is used when the remote DTE is a Packet Assembler/Disassembler (PAD). PAD CONTROL packets can control the operation of the PAD. PAD CONTROL packets received indicate success or failure in the control operations sent. For a complete description of how to control a PAD and the meaning of the response packets, consult the CCITT X.29 and X.3 Recommendations.

The use of this bit is undefined if the remote DTE is not a PAD or emulating a PAD. Therefore, the application may use it for its own purposes when PAD CONTROL packets are not used on the SVC.

Syntax for ioctl(X25_SEND_TYPE)

The syntax for the ioctl(X25_SEND_TYPE) system call and its parameters are described below.

#include <x25/x25ioctls.h>
#include <x25/x25.h>
int err;
int sd, type;
err = ioctl(sd, X25_SEND_TYPE, &type);
sd

A socket descriptor for an SVC socket. The socket need not be connected to an SVC when the ioctl() is issued.

X25_SEND_TYPE

Indicates the type of ioctl() being performed.

type

Indicates which bits are being set with this ioctl(). HP supplies three predefined values which indicate the position of these bits within type: X25_MDTF_BIT, X25_Q_BIT, and X25_D_BIT. These values represent the bits' positions and not their actual placement; that is, they must be used in a shift operation.

For example, the following expression returns an integer with the D bit set: 1 << X25_D_BIT. The M, D, and Q bits can be set in the same message, but the use of the M and D bits in the same packet are subject to CCITT specifications. Typically, the D bit is not set in the same packet as the M bit.

Once a MDTF, D, or Q bit has been turned on with the ioctl(X25_SEND_TYPE), it remains on until it is explicitly turned off with a subsequent call.

Using the MDTF Bit

The MDTF bit can be set automatically or controlled by the program. It is set automatically when you issue a send() or write() call and when you specify more data than a single packet can hold. The MDTF bit is auto matically set to link all of the packets transmitted with a single system call.

To control the use of the MDTF bit use the ioctl(X25_SEND_TYPE) call with the X25_MDTF_BIT set (set to 1). All subsequent send() or write() calls will be treated as fragments of a large message. That is, all of the packets used to send the data have their MDTF bits set.

To clear the M bit on a long message use the ioctl(X25_SEND_TYPE) with the X25_MDTF_BIT call cleared (set to 0). This must be done before the program issues the last send() or write() call in the message series. The final packet of a long message does not have the M bit set.

Setting the D Bit in CALL REQUEST Packets

Use the ioctl(X25_SEND_TYPE)call to set the D bit in a CALL REQUEST packet. Once this is done issue the connect() call to transmit the CALL REQUEST packet.

The D bit is turned of by issuing the ioctl(X25_SEND_TYPE) call after the connect() call. If this is not done, the next message will have the D bit set.

Setting the D Bit in CALL ACCEPTED Packets

To set the D Bit in CALL ACCEPTED packets:

  1. First set the listen socket so that transmission of the CALL ACCEPTED packet is controlled by the application. Use the ioctl(X25_CALL_ACPT_APPROVAL) call.

  2. When the accept() call returns, issue ioctl(X25_SEND_TYPE) on the SVC socket to set the D bit for the transmission of the CALL ACCEPTED packet.

  3. Finally, send the CALL ACCEPTED packet with the ioctl(X25_SEND_CALL_ACEPT) call.

Turn off the D bit with the ioctl(X25_SEND_TYPE) call after the ioctl(SEND_CALL_ACEPT) call; otherwise, the next message you send will have the D bit set.

Setting the D Bit in a Data Message

To use the D bit in a DATA packet, the D bit must have been set at connection time in either the CALL REQUEST packet (on the calling side) or the CALL ACCEPTED packet (on the called side).

Issue the ioctl(X25_SEND_TYPE) call to set the D bit immediately prior to issuing a send() or write() call. In blocking mode, the process is blocked until confirmation is received. If the connection has been established to use the D bit, the application can set the D bit for any data message being transmitted. A data message may be a single packet or a set of packets with the M bit set on all but the last packet.

The D bit is set on every data message transmitted until it is cleared with a second ioctl(X25_SEND_TYPE) call.

Detecting D Bit Arrival and Confirmation

If you have not set the D bit during connection establishment, you will not be able to determine if the D bit is set on an incoming message with the ioctl(X25_NEXT_MSG_STAT) described later in this chapter. When a data packet arrives with the D bit set, X.25 Level 3 will acknowledge the arrival of the packet automatically. The X.25/300 subsystem acknowledges the D bit immediately upon reception of the packet. The X.25/800 subsystem acknowledges the D bit when the packet is received, without MSG_PEEK, by the application.

If the socket is in blocking mode, the process sending data blocks until D bit confirmation arrives. If the socket is in nonblocking mode, the X.25/800 subsystem sends an out-of-band event (OOB_VC_DBIT_CONF) to the process. The arrival of a D bit confirmation can also be detected with the ioctl(X25_NEXT_MSG_STAT).

If the peer process is not using the X.25/800 subsystem, the D bit does not imply that the process has read the data. It implies only that the data has been received by the remote interface. If an end-to-end or disk-to-disk data confirmation protocol is required, it must be developed between the application processes.

Refer to the socket_x25(7) entry in your HP-UX man pages for more on ioctl(X25_SEND_TYPE).