The service interface primitives are defined in the declarations:
#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 acknowledgment */ #define ERROR_ACK 4 /* error acknowledgment */ #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 acknowledgment */ t_scalar_t PRIM_type; /* always OK_ACK */ }; struct error_ack { /* error acknowledgment */ 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 is that structure.
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 acknowledgment (ack) of BIND_REQ.
A negative acknowledgment (nak) of BIND_REQ.
Data from the network has been received.
The acknowledgment 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 acknowledgment reaches the user before any other message. For example, a UNITDATA_IND comes through before the bind is completed, the application is confused.
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
It is assumed (though not shown) that the module open procedure sets the write queue q_ptr to point at the appropriate private data structure.