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.