Solstice X.25 9.2 Developer's Guide

6.2 x25_primitives C Union

The Solstice X.25 software provides a series of data structures that determine the control part of messages passed across the NLI. The format of the control part of messages passed across the NLI is defined by structures in the following C union.

union X25_primitives {
      struct xcallf xcall; /* Connect Request/Indication */
      struct xccnff xccnf; /* Connect Confirm/Response */
      struct xdataf xdata; /* Normal, Q-bit, or D-bit data */
      struct xdatacf xdatac; /* Data ack */
      struct xedataf xedata; /* Expedited data */
      struct xedatacf xedatac; /* Expedited data ack */
      struct xrstf xrst; /* Reset Request/Indication */
      struct xrscf xrscf; /* Reset Confirm/Response */
      struct xdiscf xdisc; /* Disconnect Request/Indication */
      struct xdcnff xdcnf; /* Disconnect Confirm */
      struct xabortf abort; /* Abort Indication */
      struct xlistenf xlisten; /* Listen Command/Response */
      struct xcanlisf xcanlis; /* Cancel Command/Response */
      struct pvcattf pvcatt; /* PVC Attach */
      struct pvcdetf pvcdet; /* PVC Detach */
  }; 

All structures begin with the same members, as shown below:

typedef struct xhdrf {
      unsigned char xl_type; /* XL_CTL/XL_DAT */
      unsigned char xl_command; /* Command */
 } S_X25_HDR; 

Messages to and from applications are classified as control messages or data messages. xl_type indicates whether a message is control or data using the values XL_CTL for control and XL_DAT for data. Within each classification, the message identity is indicated by the xl_command qualifier. The combination of xl_type and xl_command must be consistent.

When sending an NLI command to the x25 driver using putmsg, the size of the data structure is determined by the command, and clearly is known in advance. The .len member of the control buffer is used to hold this value, and the.maxlen member is not used.

When reading a message with the getmsg call, the type of message cannot be known before it is received, so a buffer large enough to hold any message should be supplied. Put the size of this buffer in the.maxlen member of the control buffer structure. The actual size of the message received will be placed in the.len member on return from the getmsg call. To ensure that the buffer will be large enough, declare it as being of type union X25_primitives.

Example 6-1 shows how a getmsg can be constructed.


Example 6-1 Constructing a getmsg

#include <stream.h>
 #include <netx25/dx25_proto.h>


 struct strbuf ctlb;
 struct strbuf datab;

 union X25_primitives buffer;
 char data_buf[DATALEN];

  .
  .
  .

 ctlb.maxlen = sizeof (union X25_primitives);
 ctlb.buf = (char *)buffer;

 flag = MSG_ANY;
 datab.maxlen = DATALEN;
 datab.buf = data_buf;

 getmsg (x25_fd, &ctlb, &datab, flag);

 switch ((S_X25_HDR *)&buffer->xl_type) {
 	case N_Abort:
 			/* treat 'buffer' as an Abort message
 			 * datab.len should be 0
 			 */
 		break;

 	case N_CI:
 			/* Treat 'buffer' as a Connect Indication
 			 * data_buf[] contains Call User Data
 			 * datab.len equals length of Call User Data
 			 */
 			break;

 	.
 	.
 	.

 	};