Solstice X.25 9.2 Developer's Guide

12.7.2 X25_SET_FACILITY/X25_GET_FACILITY ioctls


Note -

The sockets-based interface provides access only to those facilities that were supported in SunNet X.25 7.0. These are a subset of the facilities supported in Solstice X.25 9.2.


The X25_SET_FACILITY ioctl command is used to set the following facilities:

reverse charge   (*)   (#)
 fast select   (*)   (#)
 non-default packet size   (*)
 non-default window size   (*)
 non-default throughput   (*)
 minimum throughput class   (#)
 closed user group   (*)   (#)
 RPOA selection   (*)   (#)
 network transit delay   (#)
 end-to-end transit delay
 network user identification   (#)
 charging information request
 expedited data negotiation
 called AEF
 calling AEF   (#)
 non-X.25 facilities

All of the above facilities can be sent in a Call Request packet. The ones that can be used with a 1980 X.25 interface are marked with an (*), although only the basic forms of the closed user group facility and the RPOA selection can be used in this case. The ones that cannot be sent in a Call Accepted packet are marked with a (#). Solstice X.25 does not permit users to set facilities in Clear Request and Clear Confirm packets.

All of the above facilities can be read using the X25_GET_FACILITY ioctl command. In addition, the following can also be read:

charging information, monetary unit
 charging information, segment
 charging information, call duration
 called line address modified notification
 call redirection notification

Sample programs provided with Solstice X.25 illustrate the use of these facilities. Here, we discuss each of the above facilities in more detail and provide code segments to illustrate their use. For convenience, the variables used in the discussion below are declared here. (Chapter 13, Sockets Programming Example" has a listing of the relevant data structures used by the X25_SET_FACILITY and X25_GET_FACILITY ioctl commands.)

FACILITY    f;   /* facility structure */
 int s;           /* socket */
 int    error;    /* ioctl return value */ 

For brevity, the value returned by ioctl calls is not checked for error.

In the discussion that follows, we show how the user can send facilities in the Call Request packet. In order to send a facility in the Call Accepted packet, the listener should either set the facility before invoking listen, or should set it before causing the Call Accepted packet to be sent (that is, the listener should have used the X25_CALL_ACPT_APPROVAL ioctl command, described later, to cause Solstice X.25 to permit call approval by the user).

The exceptions to this are end-to-end transit delay, expedited data negotiation, Called AEF, and non-X.25 facilities. To send these in the Call Accepted packet, the listener must do call approval, and must set these facilities after accept returns, but before the X25_SEND_CALL_ACPT ioctl command is used to send the Call Accepted packet.

12.7.2.1 Reverse Charge

There are two possible values for this facility: 1 indicates reverse charging, and 0 indicates no reverse charging.

This is set as follows:

u_char    reverse_charge;
 reverse_charge = 1;
 f.type = T_REVERSE_CHARGE;
 f.f_reverse_charge = reverse_charge;
 error = ioctl(s, X25_SET_FACILITY, &f); 

This facility is read as follows:

f.type = T_REVERSE_CHARGE;
 error = ioctl(s, X25_GET_FACILITY, &f);
 reverse_charge = f.f_reverse_charge;

Setting this facility before making the connect call causes this facility to be sent in the Call Request. Setting this facility before making the listen call causes Incoming Calls with the reverse charging facility to be accepted. (Calls that are not reverse-charged are always acceptable.) The listener should read the value of the facility after the accept call returns to find out if the call is reverse-charged.


Note -

Reverse charging must be allowed for this ioctl to work. You allow for reverse charging in the x25tool CUG and Facilities window. To access the CUG and Facilities window, from the x25tool Link Editor window, select CUG and Facilities. Click on Incoming Reverse Charging. See Solstice X.25 9.2 Administration Guide for further details.


12.7.2.2 Fast Select

There are three possible values for this facility. FAST_OFF indicates that fast select is not in effect. FAST_CLR_ONLY indicates fast select with restriction on response, and FAST_ACPT_CLR indicates fast select with no restriction on response.

This is set as follows:

u_char fast_select_type;
 fast_select_type = FAST_CLR_ONLY;
 f.type = T_FAST_SELECT_TYPE;
 f.f_fast_select_type = fast_select_type;
 error = ioctl(s, X25_SET_FACILITY, &f); 

This is read as follows:

f.type = T_FAST_SELECT_TYPE;
 error = ioctl(s, X25_GET_FACILITY, &f);
 fast_select_type = f.f_fast_select_type;

If this facility is set before making the connect call, the Call Request packet is sent out with this facility. If this facility is set before making the listen call, the behavior that follows will depend on whether or not restriction on response was indicated, and on whether the Incoming Call has this facility. In order for an Incoming Call bearing the fast select facility to be acceptable, the listener should have specified fast select (with or without restriction). However, an Incoming Call not bearing the fast select facility will still be acceptable to a listener who has specified fast select with no restriction on response. The type of fast select in effect will be either the type of fast select in the Incoming Call, or fast select with restriction on response if either end of the connection has specified fast select with restriction on response. If the Incoming Call does not specify fast select, and is accepted by a listener who has specified fast select with no restriction on response, fast select will not be in effect for the duration of the call.

A listener that has specified fast select (with or without restriction) must use the X25_SEND_CALL_ACPT ioctl to accept the call or use close to clear the call, after successful completion of the accept call, regardless of whether fast select is in effect for the call. If the type of fast select in effect after accept is either FAST_OFF or FAST_ACPT_CLR, the user may either accept or clear the call. If the type of fast select in effect is FAST_CLR_ONLY, the user cannot accept the call (it can only be cleared). The handling of user data in conjunction with fast select is described later.

12.7.2.3 Packet Size

Packet size is set in the Call Request packet as follows:

u_short sendpktsize, recvpktsize;
 /* set sendpktsize, recvpktsize to desired values */
 f.type = T_PACKET_SIZE;
 f.f_sendpktsize = sendpktsize;
 f.f_recvpktsize = recvpktsize;
 error = ioctl(s, X25_SET_FACILITY, &f);

It is read as follows:

f.type = T_PACKET_SIZE;
 error = ioctl(s, X25_GET_FACILITY, &f);
 sendpktsize = f.f_sendpktsize;
 recvpktsize = f.f_recvpktsize; 

Setting packet size in the Call Request causes the values set to be proposed for the call (a zero value indicates the default for the link). Reading the value after the call is set up yields the result of negotiation.

Packet sizes are set and read in bytes, so that, for example, 128, 256, and 512 are legal values.

12.7.2.4 Window Size

Window size is set in the Call Request packet as follows:

u_short   sendwndsize, recvwndsize;
 /* set sendwndsize, recvwndsize to desired values */
 f.type = T_WINDOW_SIZE;
 f.f_sendwndsize = sendwndsize;
 f.f_recvwndsize = recvwndsize;
 error = ioctl(s, X25_SET_FACILITY, &f);

It is read as follows:

f.type = T_WINDOW_SIZE;
 error = ioctl(s, X25_GET_FACILITY, &f);
 sendwndsize = f.f_sendwndsize;
 recvwndsize = f.f_recvwndsize;

Setting the window size in the Call Request causes the values set to be proposed for the call (a zero value indicates the default for the link). Reading the value after the call is set up yields the result of negotiation.

12.7.2.5 Throughput

Throughput is set in the Call Request packet as follows:

u_char      sendthruput, recvthruput;
 /* set sendthruput, recvthruput to desired values */
 f.type = T_THROUGHPUT;
 f.f_sendthruput = sendthruput;
 f.f_recvthruput = recvthruput;
 error = ioctl(s, X25_SET_FACILITY, &f); 

It is read as follows:

f.type = T_THROUGHPUT;
 error = ioctl(s, X25_GET_FACILITY, &f);
 sendthruput = f.f_sendthruput;
 recvthruput = f.f_recvthruput;

When throughput is set in the Call Request, the values set are proposed for the call (a zero value indicates the default for the link). Reading the value after the call is set up yields the result of negotiation.

12.7.2.6 Minimum Throughput Class

Minimum throughput class is set in the Call Request packet as follows:

u_char      min_sendthruput, min_recvthruput;
 /* set min_sendthruput, min_recvthruput to desired values */
 f.type = T_MIN_THRU_CLASS;
 f.f_min_sendthruput = min_sendthruput;
 f.f_min_recvthruput = min_recvthruput;
 error = ioctl(s, X25_SET_FACILITY, &f); 

It is read as follows:

f.type = T_MIN_THRU_CLASS;
 error = ioctl(s, X25_GET_FACILITY, &f);
 min_sendthruput = f.f_min_sendthruput;
 min_recvthruput = f.f_min_recvthruput; 

This facility may only be set in a Call Request packet, and read from an Incoming Call packet. The receiver of the Incoming Call packet should clear the call (with an appropriate diagnostic) if the proposed minimum throughput values cannot be supported.

12.7.2.7 Closed User Group

The user may set one of three types of Closed User Group facility: CUG_REQ (no outgoing access), CUG_REQ_ACS (with outgoing access), and CUG_BI (bilateral CUG). For CUG_REQ and CUG_REQ_ACS, the CUG is a decimal integer in the range 0-9999 (for 1980 X.25 interfaces, the valid range is 0-99). The extended form of the facility is used for CUG indices in the range 100-9999. This facility is set as follows:

u_short      cug_index;
 /* set cug_index to appropriate value */
 f.type = T_CUG;
 f.f_cug_req = CUG_REQ;    /* could be CUG_REQ_ACS or CUG_BI */
 f.f_cug_index = cug_index;
 error = ioctl(s, X25_SET_FACILITY, &f);
 

To read this facility:

f.type = T_CUG;
 error = ioctl(s, X25_GET_FACILITY, &f);
 cug_req = f.f_cug_req;
 cug_index = f.f_cug_index;

12.7.2.8 RPOA Selection

Solstice X.25 supports the setting of up to three (MAX_RPOA) RPOA transit networks (in the extended form). If only one is specified, the non-extended form of the facility is used. An RPOA transit network is specified as a decimal integer in the range 0-9999.

This facility is set as follows:

u_short      rpoa0, rpoa1, rpoa2;
 /* set rpoa0, rpoa1, rpoa2 */
 f.type = T_RPOA;
 f.f_nrpoa = 3;
 f.f_rpoa_index[0] = rpoa0;
 f.f_rpoa_index[1] = rpoa1;
 f.f_rpoa_index[2] = rpoa2;
 error = ioctl(s, X25_SET_FACILITY, &f);

To read this facility:

f.type = T_RPOA;
 error = ioctl(s, X25_GET_FACILITY, &f);
 rpoa0 = f.f_rpoa_index[0];
 rpoa1 = f.f_rpoa_index[1];
 rpoa2 = f.f_rpoa_index[2];

12.7.2.9 Network Transit Delay

The Transit Delay Selection and Indication facility (TDSAI) is set in the Call Request as follows:

u_short    tr_delay;   /* desired transit delay in milliseconds */
 /* set tr_delay */
 f.type = T_TR_DELAY;
 f.f_tr_delay = tr_delay;
 error = ioctl(s, X25_SET_FACILITY, &f);

This is read as follows:

f.type = T_TR_DELAY;
 error = ioctl(s, X25_GET_FACILITY, &f);
 tr_delay = f.f_tr_delay; 

12.7.2.10 End-to-End Transit Delay

This is set in the Call Request as follows:

u_short   req_delay, desired_delay, max_delay;
 /* set the requested, desired, and maximum delays */
 f.type = T_ETE_TR_DELAY;
 f.f_req_delay = req_delay;
 f.f_desired_delay = desired_delay;
 f.f_max_delay = max_delay;
 error = ioctl(s, X25_SET_FACILITY, &f); 

This is read as follows:

f.type = T_ETE_TR_DELAY;
 error = ioctl(s, X25_GET_FACILITY, &f);
 req_delay = f.f_req_delay;
 desired_delay = f.f_desired_delay;
 max_delay = f.f_max_delay; 

If f_desired_delay is set, f_req_delay must be non-zero; if f_max_delay is set, f_desired_delay must be non-zero. Delay is specified in milliseconds.

12.7.2.11 Network User Identification

This is set as follows (in the example below, NUI is an ASCII string):

char   nui_str[] = "sunhost";
 f.type = T_NUI;
 f.f_nui.nui_len = strlen(nui_str);
 bcopy(nui_str, f.f_nui.nui_data, strlen(nui_str));
 error = ioctl(s, X25_SET_FACILITY, &f); 

Solstice X.25 permits a maximum length of 64 (MAX_NUI) for Network User Identification facility.

To read this facility:

f.type = T_NUI;
 error = ioctl(s, X25_GET_FACILITY, &f);
 nui_str = f.f_nui.nui_data;

12.7.2.12 Charging Information Request

This write-only facility is set as follows:

f.type = T_CHARGE_REQ;
 f.f_charge_req = 1;
 error = ioctl(s, X25_SET_FACILITY, &f);

12.7.2.13 Charging Information

By setting f.type to T_CHARGE_REQ as specified above you make available the following read-only facilities. The facility types are T_CHARGE_MU, T_CHARGE_SEG, and T_CHARGE_DUR. For example, the Charging Information (monetary unit) is read as follows:

typedef struct charge_info_s {
    u_char   charge_len;
 #define MAX_CHARGE_INFO   64
    u_char   charge_data[MAX_CHARGE_INFO];
 } CHARGE_INFO;

 CHARGE_INFO charge_mu;
 f.type = T_CHARGE_MU;
 error = ioctl(s, X25_GET_FACILITY, &f);
 charge_mu = f.f_charge_mu; 

The T_CHARGE_SEG and T_CHARGE_DUR facilities are read in a way similar to the T_CHARGE_MU example above; that is, by using T_CHARGE_SEG or T_CHARGE_DUR for the f.type value, and using f_charge_seg or f_charge_dur in place of f_charge_mu.

The maximum length for the charging information facility permitted by Solstice X.25 is 64 (MAX_CHARGE_INFO). This facility should be read after the call is cleared, but before the socket is closed, since it is received in the Clear Request or Clear Confirm packets.

12.7.2.14 Called Line Address Modified Notification

This is a read-only facility received in either the Call Accepted or Clear Indication packets. It is read as follows:

u_char   line_addr_mod;
 f.type = T_LINE_ADDR_MOD;
 error = ioctl(s, X25_GET_FACILITY, &f);
 line_addr_mod = f.f_line_addr_mod;

12.7.2.15 Call Redirection Notification

This is a read-only facility received in either the Call Accepted or Clear Indication packets. It is read as follows:

typedef struct call_redir_s {
    u_char   cr_reason;
    u_char   cr_hostlen;
    u_char   cr_host[(MAXHOSTADR+1)/2];
 } CALL_REDIR;

 CALL_REDIR call_redir;
 f.type = T_CALL_REDIR;
 error = ioctl(s, X25_GET_FACILITY, &f);
 call_redir = f.f_call_redir; 

12.7.2.16 Expedited Data Negotiation

This facility is set as follows:

u_char expedited = 1;/* 0 indicates non-use of expedited data */
 f.type = T_EXPEDITED;
 f.f_expedited = expedited;
 error = ioctl(s, X25_SET_FACILITY, &f);

It is read as follows:

f.type = T_EXPEDITED;
 error = ioctl(s, X25_GET_FACILITY, &f);
 expedited = f.f_expedited;

12.7.2.17 Called/Calling AEF

There are three types of address extensions: OSI NSAP (AEF_NSAP), Partial OSI (AEF_PARTIAL_NSAP), and Non-OSI (AEF_NON_OSI). The Calling AEF may only be present in the Call Request packet.

Solstice X.25 9.2 Administration Guide describes how Solstice X.25 may be set up to automatically supply the Calling AEF (referred to as address extension) in a Call Request packet.

The Called AEF is set as follows:

typedef struct aef_s {
    u_char   aef_type;
 #define AEF_NONE      0
 #define AEF_NSAP      1
 #define AEF_PARTIAL_NSAP   2
 #define AEF_NON_OSI      3
    u_char   aef_len;
 #define MAX_AEF   40
    u_char   aef[(MAX_AEF+1)/2];
 } AEF;

 AEF   aef;
 aef.aef_type = AEF_NON_OSI;
 aef.aef_len = 7;        /* length in nibbles */
 aef.aef[0] = 0x12;
 aef.aef[1] = 0x34;
 aef.aef[2] = 0x56;
 aef.aef[3] = 0x70;      /* Note, unused nibble is zero */
 f.type = T_CALLED_AEF;
 f_called_aef = aef;
 error = ioctl(s, X25_SET_FACILITY, &f); 

The Called AEF is read as follows:

f.type = T_CALLED_AEF;
 error = ioctl(s, X25_GET_FACILITY, &f);
 aef = f_called_aef;

The Calling AEF is set and read similarly (using T_CALLING_AEF in place of T_CALLED_AEF and f_calling_aef in place of f_called_aef).

12.7.2.18 Non-X.25 Facilities

These are for expert use only. Solstice X.25 permits a maximum of 64 (MAX_PRIVATE) bytes of non-X.25 facilities. These are not looked at by Solstice X.25, but just passed through. Non-X.25 facilities consist of a sequence of facility blocks, where each block begins with a facility marker indicating non-X.25 facilities supported by either the local or remote network, or some arbitrary facility marker. This is set as follows:

typedef struct private_fact_s {
    u_char   p_len;   /* total length of facilities*/
 #define MAX_PRIVATE  64
    u_char   p_fact[MAX_PRIVATE];
       /* facilities exactly as they
        * are present in Call Request or
        * Call Accept packets
        */
 } PRIVATE_FACT;

 PRIVATE_FACT  private;
 /* set the p_len and p_fact fields */
 f.type = T_PRIVATE;
 f.f_private = private;
 error = ioctl(s, X25_SET_FACILITY, &f);

It is read as follows:

f.type = T_PRIVATE;
 error = ioctl(s, X25_GET_FACILITY, &f);
 private = f.f_private;

12.7.2.19 Determining Which Facilities are Present

Since facilities can be read only one at a time, the user needs a way to determine which facilities are present. Solstice X.25 provides the following mechanism for doing this.

The user can read a bit mask that has one bit reserved for each of the facilities described above. This is read as:

u_int     fmask;
 f.type = T_FACILITIES;
 error = ioctl(s, X25_GET_FACILITY, &f);
 fmask = f.f_facilities; 

The following mask bits are defined:

F_REVERSE_CHARGE    /* reverse charging */
 F_FAST_SELECT_TYPE  /* fast select */
 F_PACKET_SIZE       /* packet size */
 F_WINDOW_SIZE       /* window size */
 F_THROUGHPUT        /* throughput */
 F_MIN_THRU_CLASS    /* minimum throughput class */
 F_CUG               /* closed user group selection */
 F_RPOA              /* ROPA transit network */
 F_TR_DELAY          /* network transit delay */
 F_ETE_TR_DELAY      /* end to end transit delay */
 F_NUI               /* network user identification */
 F_CHARGE_REQ        /* charging information request */
 F_CHARGE_MU         /* charging information, monetary unit */
 F_CHARGE_SEG        /* charging information, segment */
 F_CHARGE_DUR        /* charging information, call duration */
 F_LINE_ADDR_MOD     /* called line address modified notification */
 F_CALL_REDIR        /* call redirection notification */
 F_EXPEDITED         /* expedited data negotiation */
 F_CALLED_AEF        /* called AEF */
 F_CALLING_AEF       /* calling AEF */
 F_PRIVATE           /* non-X.25 facilities */ 

For example, to determine if the Call Redirection facility has been received, the following segment of code could be used:

if ((fmask & F_CALL_REDIR) != 0) {
 /*
  * Read its value.
  */
 CALL_REDIR call_redir;
 f.type = T_CALL_REDIR;
 error = ioctl(s, X25_GET_FACILITY, &f);
 call_redir = f.f_call_redir;
 }