The service interface primitives are defined in the declarations shown in the following example:
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stream.h>
#include <sys/errno.h>
/* Primitives initiated by the service user */
#define BIND_REQ 1 /* bind request */
#define UNITDATA_REQ 2 /* unitdata request */
/* Primitives initiated by the service provider */
#define OK_ACK 3 /* bind acknowledgement */
#define ERROR_ACK 4 /* error acknowledgement */
#define UNITDATA_IND 5 /* unitdata indication */
/*
* The following structures define the format of the
* stream message block of the above primitives.
*/
struct bind_req { /* bind request */
t_scalar_t PRIM_type; /* always BIND_REQ */
t_uscalar_t BIND_addr; /* addr to bind */
};
struct unitdata_req { /* unitdata request */
t_scalar_t PRIM_type; /* always UNITDATA_REQ */
t_scalar_t DEST_addr; /* dest addr */
};
struct ok_ack { /* ok acknowledgement */
t_scalar_t PRIM_type; /* always OK_ACK */
};
struct error_ack { /* error acknowledgement */
t_scalar_t PRIM_type; /* always ERROR_ACK */
t_scalar_t UNIX_error; /* UNIX system error code*/
};
struct unitdata_ind { /* unitdata indication */
t_scalar_t PRIM_type; /* always UNITDATA_IND */
t_scalar_t SRC_addr; /* source addr */
};
union primitives { /* union of all primitives */
long type;
struct bind_req bind_req;
struct unitdata_req unitdata_req;
struct ok_ack ok_ack;
struct error_ack error_ack;
struct unitdata_ind unitdata_ind;
};
struct dgproto { /* structure minor device */
short state; /* current provider state */
long addr; /* net address */
};
/* Provider states */
#define IDLE 0
#define BOUND 1
In general, the M_PROTO or M_PCPROTO block is described by a data structure containing the service interface information in this example, union primitives.
The module recognizes two commands:
Give this stream a protocol address (for example, give it a name on the network). After a BIND_REQ is completed, data from other senders will find their way through the network to this particular stream.
Send data to the specified address.
The module generates three messages:
A positive acknowledgement (ack) of BIND_REQ.
A negative acknowledgement (nak) of BIND_REQ.
Data from the network has been received.
The acknowledgement of a BIND_REQ informs the user that the request was syntactically correct (or incorrect if ERROR_ACK). The receipt of a BIND_REQ is acknowledged with an M_PCPROTO to ensure that the acknowledgement reaches the user before any other message. For example, if a UNITDATA_IND comes through before the bind is completed, the application cannot send data to the proper address
The driver uses a per-minor device data structure, dgproto, which contains the following:
Current state of the service provider IDLE or BOUND.
Network address that has been bound to this stream.
The module open procedure is assumed to have set the write queue q_ptr to point at the appropriate private data structure, although this is not shown explicitly.