/*        sys.h      2.00.000 01JUN99 01:23  */
#ifndef   sys_h__
#define   sys_h__

#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
/******************************************************************************
 * SYS : SYSTEM SUPPLIED ROUTINES AND PRIMITIVES
 ******************************************************************************
 *
 * This header file represents system supplied routines and primitives grouped
 * into seven categories:
 *
 * SYS     : System conventions.
 *
 * SYSMEM  : General memory allocation.
 *
 * SYSPDU  : Protocol buffer allocation, access, transmit and receive.
 *
 * SYSTIME : Scheduling routines : immediate, in fixed (approximate) time, in
 *           random time period.
 *
 * SYSNODE : System internal and external connections between protocol modules,
 *           their users, thir owners, and the services they use.
 *
 * SYSLAN  : LAN attachment, transmission and reception handles.
 *
 * SYSERR  : System error routines for gross errors in program logic detected
 *           in the course of execution, for which there is no sensible course
 *           of action at the point of detection.
 */
/******************************************************************************
 * SYS : SYSTEM CONVENTIONS
 ******************************************************************************
 */

typedef enum {False = 0, True = 1} Boolean;

typedef Boolean Flag;
        enum   {Off = False, On = True};

enum {Zero = 0, One = 1, Two = 2};

typedef unsigned char   Octet;

typedef unsigned short  Int16;

typedef unsigned char   Mac_address[6];

typedef unsigned short  Ethertype;

typedef unsigned short  Port_no;

/******************************************************************************
 * SYS : SYSTEM INITIALIZATION
 ******************************************************************************
 */

extern void sys_init();

/******************************************************************************
 * SYS : SYSTEM SUPPLIED MEMORY ALLOCATION ROUTINES
 ******************************************************************************
 */

extern Boolean sysmalloc(int size, void **allocated);

extern void    sysfree(void *allocated);


/******************************************************************************
 * SYSPDU : SYSTEM SUPPLIED PDU ACCESS PRIMITIVES
 ******************************************************************************
 */

typedef void   Pdu;

extern Boolean syspdu_alloc(Pdu **pdu);

extern void    syspdu_free( Pdu  *pdu);

extern Boolean rdcheck(     Pdu  *pdu, int number_of_octets_remaining);

extern Boolean rdoctet(     Pdu  *pdu, Octet *val);

extern Boolean rdint16(     Pdu  *pdu, Int16 val);

extern Boolean rdskip(      Pdu  *pdu, int number_to_skip);

extern void    syspdu_tx(   Pdu  *pdu, int port_no);

/******************************************************************************
 * SYSTIME : SYSTEM SUPPLIED SCHEDULING FUNCTIONS
 ******************************************************************************
 */

typedef int Time;
typedef int Ticks;
enum       {Tick       = (Time) 1};
enum       {Zero_ticks = (Time) 0};
enum       {Stopped    = (Time) 0};
enum       {Expired    = (Time) 0};
enum       {Expiring   = (Time) 1};
enum       {Now        = (Time) 0};

typedef struct timer Timer;

struct timer
{
   Timer *next_timer;

   Time   expiry_at;

   void (*expiry_fn)(void *);
   void  *expiry_arg;
};

extern void sys_create_timer( Timer *timer, void (*call_fn)(void *),
                                            void *with_arg);
extern void sys_null_timer(   Timer *timer);
static void sys_destroy_timer(Timer *timer);
extern void sys_start_timer(  Timer *timer, Time to_run);
extern void sys_stop_timer(   Timer *timer);
extern void sys_cstop_timer(  Timer *timer);
extern void sys_tick();

extern void systime_start_random_timer(int process_id,
					void (*expiry_fn)(void *, int instance_id),
					int    instance_id,
					int    timeout);

extern void systime_start_timer(int    process_id,
								void (*expiry_fn) (void *, int instance_id),
								int    instance_id,
								int    timeout);

extern void systime_schedule(int    process_id,
						     void (*expiry_fn) (void *, int instance_id),
							 int    instance_id);

extern Boolean sys_check_expiry(Ticks *user_timing_down_counter);

#if !NDEBUG
extern int sys_time();
#endif

/******************************************************************************
 * SYSNODE : PROTOCOL MODULE INTERCONNECTION
 ******************************************************************************
 */

typedef struct node Node;
typedef int         Node_id;

struct node
{
   Node   *next;     /*  reserved for owner                             */
   void   *owner;    /* 'control' port                                  */
   Node   *pnext;    /*  reserved for provider->owner                   */
   Node   *provider; /* 'down'    port, transmits to, and receives from */
   Node   *user;     /* 'up'      port, receives to, and transmits from */

   Node_id node_id;

   /* functions called by service provider : */

   void  (*rx_fn       )(Node *,  /*  this node     */
                         void *   /*  pdu           */
                        );
   void  (*tx_fn       )(Node *,  /*  this node     */
                         void *   /*  pdu           */
                        );

   void  (*rx_status_fn)(Node *,  /*  this node     */
                         Boolean, /*  enabled       */
                         void *   /*  optional args */
                        );
   void  (*tx_status_fn)(Node *,  /*  this node     */
                         Boolean, /*  enabled       */
                         void *   /*  optional args */
                        );

   Boolean rx_on;     /* owner's instructions to provider */
   Boolean tx_on;     /*               ''                 */

   Boolean rx_enabled; /* service provider's current state */
   Boolean tx_enabled; /*               ''                 */
};

extern void     init_node(       Node *node, void *owner);
extern  Boolean isolated_node(   Node *node);
extern  void    sys_attach_node( Node *to,   Node *node);
extern  void    sys_rx(          Node *node, void  *pdu);
extern  void    sys_node_rx(     Node *node, void  *pdu);
extern  Boolean sys_tx(          Node *node, void  *pdu);
extern  void    sys_node_tx(     Node *node, void  *pdu);
extern  void    sys_node_rx_status(Node *node, Boolean yes, void *arg);
extern  void    sys_node_tx_status(Node *node, Boolean yes, void *arg);

/******************************************************************************
 * SYSLAN : LAN ATTACHMENT, TRANSMISSION AND RECEPTION.
 ******************************************************************************
 */
typedef Node    Lan;

extern  Boolean sys_create_lan(     Lan **lan);
extern  void    sys_attach_lan_node(Lan  *lan, Node  *mac);
extern  void    sys_detach_lan_node(Node *mac);
extern  void    sys_lan_tx(         Node *node, void  *pdu);

/******************************************************************************
 * SYSERR : FATAL ERROR HANDLING
 ******************************************************************************
 */

extern syserr_panic();

#endif /* sys_h__ */

