Solstice X.25 9.2 Developer's Guide

12.4 Sending Data

The send call is used to send data over a virtual circuit. send is passed the socket, a pointer to the data to be transmitted, the length of the data, and a flag indicating the type of data to be sent. Interrupt data is sent by setting flags to MSG_OOB. Otherwise, flags should be set to zero. The returned count indicates the number of bytes transmitted by send.

int count, len, flags, s;
 char *msg;
 count = send(s, msg, len, flags);

Note that for normal data, you can use the write system call instead of send. The call:

write(s, msg, len) 

is equivalent to:

send(s, msg, len, 0)

The X.25 protocol has the concept of an X.25 message. A complete X.25 message is a sequence of one or more packets with the M-bit (More bit) set in all but the final packet. Normally, X.25 sends the data specified in a send call as a complete message. This means that the data will be segmented into packets as required by the PSDN, and the M-bit will be set in all but the final packet. If the user wishes to pass the data in a complete X.25 message in pieces (that is, using multiple send calls), the setting of the M-bit must be controlled using the X25_SEND_TYPE ioctl as described below.


Note -

In the current release of Solstice X.25, send() returns a positive result after a virtual circuit is closed at the remote end. This behavior is different from SunNet X.25 7.0. To be notified when the virtual circuit has been closed, use the X25_OOB_ON_CLEAR ioctl, as described in "12.7.8 Accessing the Diagnostic Code".


12.4.1 Control of the M-, D-, and Q-bits

The settings of M-, D- and Q-bits in transmitted packets are changed by means of the X25_SEND_TYPE ioctl call.

ints, send_type;
 error = ioctl(s, X25_SEND_TYPE, &send_type);

send_type provides the new settings of the M-, D-, and Q-bits. The M-, D-, and Q-bits are encoded into the send_type field by bit shifting as shown below.

#define M_BIT 0       /* number of bits to shift to set "more"
        * bit */
 #define D_BIT 2       /* number of bits to shift to set end-to-end
        * acknowledge bit */
 #define Q_BIT 3       /* number of bits to shift to set qualified
        * data bit */

For example, to set the Q-bit in a packet:

intsend_type = (1 << Q_BIT), s;
 error = ioctl(s, X25_SEND_TYPE, &send_type); 

M_BIT determines whether or not a packet is the final piece of a complete X.25 message. If M_BIT is set, subsequent send calls are treated as part of a single X.25 message. If M_BIT is not set, the next send ends the current X.25 message. For example, the following code allows a complete X.25 message to be sent in three pieces:

ints, send_type, error;
 /* Set M_BIT to indicate multiple pieces */
 send_type = (1 << M_BIT);
 error = ioctl(s, X25_SEND_TYPE, &send_type);
 /* send first piece */
 error = send(s, &first_piece, sizeof(first_piece), 0);
 /* send next piece */
 error = send(s, &second_piece, sizeof(second_piece), 0);
 /* Clear M_BIT to indicate end of message */
 send_type = 0;
 error = ioctl(s, X25_SEND_TYPE, &send_type);
 /* send final piece */
 error = send(s, &final_piece, sizeof(final_piece), 0);   

If the M-bit is turned on using the X25_SEND_TYPE ioctl, it will stay turned on until it is turned off. The X.25 recommendation states that the M-bit shall be turned on only in packets that are "full"--that is, packets that have the maximum size for that virtual circuit. So if the M-bit is turned on, and the next send does not supply a full X.25 packet, X.25 will wait until enough send calls have been issued to build a full X.25 packet before transmitting the next packet with the M-bit turned on.

The Q-bit qualifies the data in Data packets. A local DTE sets the Q-bit to indicate that the data being sent is significant for a device connected to the remote DTE. It is often used by a remote host when sending control packets to a PAD, to distinguish the control packets from packets containing user data.

The D-bit allows a local DTE to specify end-to-end acknowledgment of data packets. Normally, a DTE receives acknowledgement only from its local DCE. The D-bit is significant only in call setup and data packets.

D_BIT and Q_BIT control the settings of those bits in an X.25 packet. These bits are manipulated in the same manner as the M_BIT was above. Since the X.25 recommendation states that the D_BIT and Q_BIT bits should remain constant for each packet in a complete X.25 message, D_BIT and Q_BIT should only be changed at the beginning of an X.25 message.

Unlike M_BIT, D_BIT and Q_BIT are turned off automatically after a complete X.25 message has been sent. Hence, to set these bits in a series of complete X.25 messages, you should turn them on at the start of each complete X.25 message. If the complete X.25 message is a sequence of full packets with the more bit turned on in all but the last packet in the sequence, the setting of D_BIT and Q_BIT will be the same for all the packets unless you explicitly change the setting in between.

12.4.2 Sending Interrupt and Reset Packets

An interrupt packet may be sent in the following manner. The interrupt user data is contained in intr:

int s;
 char intr = 0;       /* set this variable to contain the interrupt
                       * user data (in this case 0) */
 error = send(s, &intr, 1, MSG_OOB);

If the link supports 1984 X.25, you may send up to 32 bytes of interrupt data. On 1980 links, you may send only one byte.

A reset packet may be sent in the following manner:

X25_CAUSE_DIAG diag;
 int error, s;
 diag.flags = 0;
 diag.datalen = 2;
 diag.data[0] = 0;          /* cause */
 diag.data[1] = 67;         /* diagnostic */
 error = ioctl(s, X25_WR_CAUSE_DIAG, &diag);

This will cause a Reset to be sent with the cause code and diagnostic specified by the user. See "12.7.8 Accessing the Diagnostic Code" of this chapter for more information.