HPlogo X25/9000: X.25/9000 Programmer's Guide > Chapter 5  Receiving and Transmitting Out-of-Band Information

Building a Signal Handler

» 

Technical documentation

Complete book in PDF

 » Table of Contents

 » Index

A signal handler is a routine that is called when a signal arrives. The signal handler executes in the process address space and all global data items are available to the signal handler. The process is halted while the signal handler executes. When the signal handler returns, the process resumes execution at the point where it was halted.

There are four steps that a signal handler should perform each time it is executed:

  1. Obtain the cause for the signal being sent.

    To obtain the out-of-band event that caused the signal handler to be executed in the first place, use the recv() system call with the MSG_OOB flag set. recv(MSG_OOB) returns a buffer. The first byte in the buffer contains the number of bytes in the event (range: 3 to 34 bytes). The second byte contains the event code (described below) and the rest of the buffer contains the event data, if any.

    The recv(MSG_OOB) call is nonblocking. If the recv() call returns 0, then no out-of-band events were queued. If the call returns a negative value, an error occurred. A value greater than 0 indicates the size of the buffer being returned.

  2. Process the event which caused the signal to be sent.

    After the cause of the event has been received, the signal handler should process the event. Usually out-of-band events have an effect on the state of the VC. For example, the arrival of a CLEAR INDICATION packets makes the VC unusable. This information should be made known to the main program. Typically, this is done with globally-defined state variables. The state variables can be tested by the main program, or examined only after a system call returns with an error. Many of the state changes of a VC are made known to the process through errno when a system call is executed.

    The actual strategy used to pass information to the main program is up to the application designer.

    Possible out-of-band events, and the appropriate actions for each, are described below.

  3. Obtain any out-of-band events which may have arrived while the signal handler was executing.

    No more than one signal of the same type can be blocked while a signal handler is operating. If a second signal arrives, the first is lost. To ensure there is no loss of data, once the signal handler is executed, it should obtain all of the data in the out-of-band queue. That is, issue recv(MSG_OOB) calls until a 0 is returned.

  4. Return execution control to the main process.

    Normal operation of the program is halted while the signal handler is executing. When it returns, processing resumes at the point at which it was interrupted.

    onurg() is a routine that handles out-of-band events in the client program.

Example of an X.25 Signal Handler

NOTE: For the purpose of simplicity, this example assumes only one socket; if you have more than one socket you can have the handler poll each socket in turn to see if OOB information has arrived.
#define MAX_EVENT_SIZE 34 
/* Define maximum OOB message size: 32 + 1 byte for the
* packet type + 1 byte for the total event size */
/* Definitions for Out-of-Band events (OOB_INTERRUPT,
* OOB_VC_CLEAR, OOB_VC_RESET and others) are stored in
* x25.h
*/
onurg(skt)
int skt
{
int error, s, n, buflen;
unsigned buf[MAX_EVENT_SIZE];

while (1)
{
buflen = MAX_EVENT_SIZE;
if ((n = recv(skt, buf, buflen, MSG_OOB)) < 0)
{
perror("recv MSG_OOB")
break;
}
else if ( n == 0 ) break;
else
switch (buf[1])
{
case OOB_INTERRUPT:
printf("INTERRUPT Packet Received\n");
for (i = 2; i < n; i++)
printf("%d ",buf[i]);
printf("\n");
break;
case OOB_VC_RESET:
printf("RESET Packet Received\n");
printf("Cause-code:%d\n",buf[2]);
if (n >= 4) printf("Diagnostic code:
%d\n",buf[3])
if (n >= 5) printf("Reason: %d\n",buf[4])
break;
case OOB_VC_CLEAR:
printf("CLEAR Packet Received\n");
printf("Cause-code:%d\n",buf[2]);
if (n >= 4) printf("Diagnostic code:
%d\n",buf[3])
if (n >= 5) printf("Reason: %d\n",buf[4])
break;
case OOB_VC_RESET_CONF:
printf("RESET CONFIRMATION Packet Received\n");
break;
case OOB_VC_INTERRUPT_CONF:
printf("INTERUPT CONFIRMATION Packet
Received\n");
break;
case OOB_VC_DBIT_CONF:
printf("D-Bit Confirmation Packet Received\n");
break;
case OOB_VC_MSG_TOO_BIG:
printf("Message Larger Than Inbound Buffer
Received\n");
break;
case OOB_VC_L2_DOWN:
printf("X.25 Level 2 is Down\n");
break;
}
}
} /* onurg */
WARNING! If the out-of-band data is not read quickly, the out-of-band data queue could overflow. If the queue overflows, subsequent out-of-band events are discarded.

The Out-of-Band Events

There are eight out-of-band (OOB) events which a signal handler can receive. The out-of-band values are defined in the x25.h include (program header) file. The out-of-band values are:

  • OOB_INTERRUPT

  • OOB_VC_CLEAR

  • OOB_VC_DBIT_CONF

  • OOB_VC_INTERRUPT_CONF

  • OOB_VC_L2DOWN

  • OOB_VC_MSG_TOO_BIG

  • OOB_VC_RESET

  • OOB_VC_RESET_CONF

The out-of-band events are described below.

OOB_INTERRUPT

An INTERRUPT packet was received. The confirmation is sent by the subsystem when reading this event, if the MSG_PEEK flag was not set.

The buffer received may contain from 3 to 34 bytes of data. The first 2 bytes of the buffer are its length and the event code respectively. The remainder of the buffer contains the interrupt data. The use of the interrupt data is application-dependent.

NOTE: The maximum number of bytes of interrupt data depends on the version of X.25 recommendations being used by the network. The 1980 X.25 recommendations permit 1 byte of interrupt data while the 1984 X.25 recommendations permit up to 32 bytes of interrupt data.

OOB_VC_CLEAR

A CLEAR INDICATION packet was received on the SVC: the SVC can no longer send or receive data, and is closed. The OOB_VC_CLEAR is always the last event in the out-of-band queue.

You can use the recv(MSG_OOB) call to read out-of-band data that arrived before the CLEAR INDICATION packet. You can also use the ioctl(X25_RD_USER_DATA) (described below) to read cleared user data, if any exists. In addition, a CLEAR INDICATION packet may contain a facilities field, that can be examined with the ioctl(X25_RD_FACILITIES) call (see “The ioctl(X25_RD_FACILITIES) Call”).

You can get information on the state of the interface with the ioctl(X25_GET_IFSTATE) call.

The first byte contains the length of the buffer, and the second byte contains the clear indication. The third byte buf[2] contains the cause code. The fifth byte byte[4] always contains 0 (zero).

Table 5-1 Title not available (OOB_VC_CLEAR)

Value

Reason

0

CLEAR INDICATION packet sent by network provider, subsystem, or X.25 device driver.

 

OOB_VC_DBIT_CONF

The D bit confirmation was received on a socket in nonblocking mode. This event can only be received on sockets in nonblocking mode, because a send() or write() with the D bit set blocks until confirmation is received. For more on D bit usage see “Controlling the MDTF, D, and Q bits”. The first byte of the buffer contains the length and the second byte contains the event code.

OOB_VC_INTERRUPT_CONF

Confirmation to a previously-sent INTERRUPT packet was received on a socket in nonblocking mode. This event can only be received on sockets in nonblocking mode, because send(OOB_MSG) blocks until interrupt confirmation is received.

The first 2 bytes of buf[] contain the buffer length and the event code respectively.

OOB_VC_L2DOWN

X.25 Level 2 is down. This event is returned only on a socket accessing a permanent virtual circuit (PVC); on an SVC, a clear indication is sent. Recover by issuing a close() on the socket, create another socket with the socket() system call, and binding the new socket to a PVC with the ioctl(X25_SET_PVC) call. Level 2 will probably not come up immediately. Level 2 usually goes down because of high noise on the line for a sustained period of time (see “Using Permanent Virtual Circuits” for a description of PVC usage).

The first 2 bytes of buf[] contain the buffer length and the event code respectively.

OOB_VC_MSG_TOO_BIG

This event usually means that a message larger than the inbound buffer size was received. The data was therefore discarded and the VC was reset. This event occurs when the receiving side's inbound buffer size is set to a value too small to receive the message. In this case you must increase this value with the setsockopt() system call to ensure that the buffer size is sufficient to receive any message which may arrive, or use the ioctl(X25_SET_FRAGMENT_SIZE) to enable the reception of message fragments.

If a shutdown(0) is issued on the socket and a DATA packet is received, a OOB_VC_MSG_TOO_BIG event will be delivered to the process and a CLEAR packet will be sent on the SVC.

The first 2 bytes of buf[] contain the buffer length and the event code respectively.

OOB_VC_RESET

A RESET INDICATION packet was received on the VC. Reading this event, without the MSG_PEEK flag set, causes a RESET CONFIRMATION packet to be sent, unblocking the sending process. A RESET can also be sent by the X.25 network provider, in which case, both ends of the VC will receive RESET INDICATION packets.

When a RESET INDICATION packet is received, the out-of-band queue is destroyed, and the RESET INDICATION data is placed in the out-of-band queue as its only event. All data that is not sent or received (normal and out- of-band data) is discarded. You must read the RESET INDICATION data before you can send further data on that connection.

The first 2 bytes of buf[] contain the buffer length and the event code respectively. The third byte buf[2] contains the cause code. The fourth byte buf[3] contains the diagnostic code. If the diagnostic code was not present in the packet, 0 is specified. The fifth byte buf[4] contains the reason the RESET INDICATION packet was sent. A 0 value indicates that the RESET INDICATION packet was sent by the network provider. Other values may be specified in the future.

After you have read the out-of-band data, you can proceed sending normal data. The connection is then ready to send and receive more data. Application programmers must provide a recovery mechanism to handle the loss of data that can occur due to a RESET INDICATION.

OOB_VC_RESET_CONF

Confirmation to a previously-sent ioctl(X25_RESET_VC) was received on a socket in nonblocking mode. This event can only be received on sockets in nonblocking mode, because in blocking mode the ioctl(X25_RESET_VC) blocks until confirmation is received.

The first 2 bytes of buf[] contain the buffer length and the event code respectively.