Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
8.  STREAMS Kernel-Level Mechanisms Driver and Module Service Interfaces Service Interface Library Example  Previous   Contents   Next 
   
 
BIND_REQ

Asks the provider to bind a specified protocol address. It requires an acknowledgement from the provider to verify that the contents of the request were syntactically correct.

UNITDATA_REQ

Asks the provider to send data to the specified destination address. It does not require an acknowledgement from the provider.

The three other primitives represent acknowledgements of requests, or indications of incoming events, and are passed from the service provider to the service user.

OK_ACK

Informs the user that a previous bind request was received successfully by the service provider.

ERROR_ACK

Informs the user that a nonfatal error was found in the previous bind request. It indicates that no action was taken with the primitive that caused the error.

UNITDATA_IND

Indicates that data destined for the user has arrived.

Module Service Interface Example

The following code is part of a module that illustrates the concept of a service interface. The module implements a simple service interface and mirrors the service interface library example. The following rules pertain to service interfaces.

  • Modules and drivers that support a service interface must act upon all PROTO messages and not pass them through.

  • Modules can be inserted between a service user and a service provider to manipulate the data part as it passes between them. However, these modules cannot alter the contents of the control part (PROTO block, first message block) nor alter the boundaries of the control or data parts. That is, the message blocks comprising the data part can be changed, but the message cannot be split into separate messages nor combined with other messages.

    In addition, modules and drivers must observe the rule that high-priority messages are not subject to flow control and forward them accordingly.

Service Primitive Declarations

The service interface primitives are defined in the declarations shown in the following example:


Example 8-17 Service Primitive 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 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:

BIND_REQ

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.

UNITDATA_REQ

Send data to the specified address.

The module generates three messages:

OK_ACK

A positive acknowledgement (ack) of BIND_REQ.

ERROR_ACK

A negative acknowledgement (nak) of BIND_REQ.

UNITDATA_IND

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:

 
 
 
  Previous   Contents   Next