#ident "$Id: x25init.c,v 1.5 1997/10/21 20:48:49 gary Exp $"
/*****************************************************************************
 * Copyright (c) 1988-95 Digi International Inc., All Rights Reserved
 * 
 * This  software  contains  proprietary  and  confidential   information   of
 * Digi International  Inc.   By  accepting  transfer  of this copy, Recipient
 * agrees to retain this software in  confidence,  to  prevent  disclosure  to
 * others,  and  to make no  use of this software other than that for which it
 * was delivered.  This is an unpublished copyright work  Digi   International
 * Inc.    Except   as   permitted   by  federal  law,  17 USC 117, copying is
 * strictly prohibited.
 * 
 * Digi  International  Inc.  CONFIDENTIAL  -   (Digi    International    Inc.
 * Confidential  when   combined   with   the   aggregated  modules  for  this
 * product) OBJECT CODE ONLY SOURCE MATERIALS
 * 
 * (C) COPYRIGHT Digi International Inc. 1995
 * 
 * All Rights Reserved
 * 
 * US   Government   Users   Restricted   Rights   -   Use,   duplication   or
 * disclosure  restricted by GSA ADP Schedule Contract with Digi International
 * Inc.
 * 
 *****************************************************************************/

/*******************************************************************
 *
 *  SpiderX25 X25 PLP Driver
 *
 *  Copyright 1991 Spider Systems Limited
 *
 *  X25INIT.C
 *
 *
 *******************************************************************/

/*
 *	x25init.c
 *	 /projects/common/PBRAIN/SCCS/pbrainF/dev/sys/x25/0/s.x25init.c
 *	@(#)x25init.c	1.22
 *
 *	Last delta created	12:39:23 4/14/92
 *	This file extracted	18:32:56 11/19/92
 *
 */

/* ----------------------------------------------------------------------
	Routines for initialisation and timers.
   ---------------------------------------------------------------------- */

/* #include <sys/param.h> */
#include "x25_inc.h"
#include "iso.h"

extern int L3monarray[] ;

#ifndef NULL
#define NULL 0
#endif


/************************************************************************/
void x25init()
/************************************************************************/

/*
    Initialise the database elements using external limits
*/

{
    int i;

    /*
	Initialise the virtual circuit database
    */
    for(i=0; i<=iMAXXVCS; i++)
    {
	iso_vc[i]=(&xisovc[i]);
	(void) bzero((bufp_t)iso_vc[i], sizeof( struct x25vcformat ) );
    }

    /*
	Initialise the PLP record database
    */
    for(i=0; i<=iMAXXLSAPS; i++)
    {
	iso_lsap[i]=(&linklsaps[i]);
	(void) bzero((bufp_t)iso_lsap[i], sizeof( struct lsformat ) );
    }

    /*
	Initialise the glue record database
    */
    for( i=0; i<iMAXXDEVS; i++)
    {
	(void) bzero((bufp_t)&xgldb[i], sizeof( struct xgldbf ) );
	xgldb[i].gref = i;
    }
	
    /*
	Initialise the subnetwork database
    */
    for( i=0; i<iMAXXSUBNETS; i++)
    {
	(void) bzero((bufp_t)&xsndb[i], sizeof( struct xsndbf ) );
	xsndb[i].linkref=i;
	xsndb[i].statptr=L3monarray+(i*mon_size) ;
    }

    /*
	Initialise the subnetwork configuration database
    */
    for( i=0; i<iMAXXCONFIG; i++)
    {
	(void) bzero((bufp_t)&xcfg[i], sizeof( struct x25cfgformat ) );
    }

    /*
	Initialise the statistics array
    */
    (void) bzero((bufp_t)L3monarray, MONARRAYSIZE * iMAXXSUBNETS);

    /*
	Initialise the listen request queue
    */
    listen_requestQ= (mblk_t *)NULL;

    /*
	Initialise NUI/facilities table
    */
    nuifac_init();
}

/* ----------------------------------------------------------------------
		Tick external counts and routines
   ---------------------------------------------------------------------- */

int x25ticks = 0;
int x25temp  = 0;
queue_t *x_ctlstrm = NULL;

/************************************************************************/
int x25clock(caddr_t Dummy)
/************************************************************************/

/*
    Clock interface for the X25 module. Its action is to schedule the
    write service procedure of the control stream if it exists. This is
    where all checking of clocks and timers are done. The clock is kept
    ticking on a 1/10th second timeout.
*/

{
    x25ticks++;
    if( x_ctlstrm != NULL )
    {
	qenable(x_ctlstrm);
	timeout(x25clock,0,HZ/10);
    }

	return 0;
}

int dllcall=0;			/* The locking device */

/************************************************************************/
void x25vccall(plpptr)
/************************************************************************/

/*
    Examine the given virtual circuit for any outstanding events.
    Not allowed if database already being processed.
*/

register struct x25vcformat FAR *plpptr;

{
    /*
	Attempt to lock the database pointers etc
    */
    if( dllcall != 0 )
    {
	return;
    }
    else
    {
	dllcall = 1;	/* Put the lock on */
    }

    /*
	Database now locked proceed
    */
    if( plpptr != NULL )
    {
	/*
	    Check call from user level. Otherwise ignore the call.
	*/
	if( plpptr->xtag  == X25TAG )
	{
	    x_exam_user(plpptr->lsaplink,plpptr);
	}
    }
    dllcall = 0;
    x25tick();
}


/************************************************************************/
void x25lscall(lsapptr)
/************************************************************************/

/*
    Examine the given PLP record for any outstanding events.
    Not allowed if database already being processed.
*/

register struct lsformat FAR *lsapptr;

{
    /*
	Attempt to lock the database pointers etc
    */
    if( dllcall != 0 )
    {
	return;
    }
    else
    {
	dllcall = 1;	/* Put the lock on */
    }

    /*
	Database now locked proceed
    */
    if( lsapptr != NULL )
    {
	/*
	    Check locked event from LAPB/LLC2. Otherwise ignore the call.
	*/
	if( lsapptr->ltag == PLPTAG )
	{
	    l_exam_user(lsapptr);
	}
    }
    dllcall = 0;
    x25tick();
}


/************************************************************************/
void x25tick()
/************************************************************************/

/*
    Decrement and check for expired timers on any active virtual circuit
    or PLP record.  Not allowed if database already being processed.
*/

{
    register struct x25vcformat FAR *plpptr;
    register struct lsformat FAR *lsapptr;
    register int s;

    /*
	Attempt to lock the database pointers etc
    */
    if( dllcall != 0 )
    {
	return;
    }
    else
    {
    	dllcall = 1;	/* Put the lock on */
    }

    /* Clock examination */

    if ( x25ticks != x25temp )
    {
	x25temp = x25ticks;

	/*
	    Check through the PLP records database
	*/
	for( s=FIRSTLSAP; s<=isolsapmax; s++ )
	{
	    lsapptr = iso_lsap[s];
	
	    /*
  		If active record then check timers
	    */
	    if( lsapptr->ltag == PLPTAG )
	    {
		l_examtimer(lsapptr);

		/*
		    Check if any events have been caused
		*/
		if( lsapptr->lusrevent != 0 )
		    l_exam_user(lsapptr);
	    }
	}

	/*
	    Check through the virtual circuit database
	*/
        for( s=FIRSTVC; s<=isovcmax; s++ )
	{
	    plpptr = iso_vc[s];

	    /*
		If active circuit then check timers
	    */
	    if( plpptr->xtag == X25TAG )
	    {
		x_examtimer(plpptr);

		/*
		    Check if any events have been caused
		*/
		if( plpptr->xusrevent != 0 )
		    x_exam_user(plpptr->lsaplink,plpptr);
	    }
        }
    }
    dllcall = 0;
}
