/*****************************************************************************

 @(#) $Id: sls_lsta.h,v 0.7.2.4 2001/02/03 05:48:54 brian Test $

 -----------------------------------------------------------------------------

 Copyright (C) 1997-2001  Brian Bidulock <bidulock@dallas.net>

 All Rights Reserved.

 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
 Foundation; either version 2 of the License, or (at your option) any later
 version.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 675 Mass
 Ave, Cambridge, MA 02139, USA.

 -----------------------------------------------------------------------------

 Last Modified $Date: 2001/02/03 05:48:54 $ by $Author: brian $

 *****************************************************************************/

#ifndef __SLS_LSTA_H__
#define __SLS_LSTA_H__

/*
 *  Referenced functions.
 *
 *  This state machine does not access any route or routeset functions.
 */

/* link and linkset functions */

static inline void lk_lsac_lsta_deactivate_link(lk_t *lk);

static inline void lk_lsla_lsta_no_terminal(lk_t *lk);
static inline void lk_lsla_lsta_terminal(lk_t *lk);

static inline void lk_lslr_lsta_no_terminal(lk_t *lk);
static inline void lk_lslr_lsta_terminal(lk_t *lk);

/*
 *  Forward declarations.
 */

static inline void lk_lsta_lsla_determine_terminal(lk_t *lk);
static inline void lk_lsta_lslr_determine_terminal(lk_t *lk);
static inline void lk_lsta_lsac_terminal_available(lk_t *lk);
static inline void lk_lsta_lsld_terminal_idle(lk_t *lk);

/*
 *  Signalling Link Management (SLM)
 *  Signalling Link Terminal Allocation (LSTA)
 *  Figure 41/Q.704
 */

static inline void lk_lsta_lsla_determine_terminal(lk_t *lk)
{
    if ( lk->statem.lsta_state == LK_STATE_IDLE ) {
        lk->statem.activation  = 1;
        lk->statem.restoration = 0;
        if ( 0 ) /* any terminals idle */ {
            /* select terminal */
        } else
        if ( 1 ) /* any terminals available */ {
            if ( lk->statem.activation  ) lk_lsla_lsta_no_terminal(lk);
            if ( lk->statem.restoration ) lk_lslr_lsta_no_terminal(lk);
        } else {
            /* select terminal */
            lk->statem.lsta_state = LK_STATE_WAIT;
            lk_lsac_lsta_deactivate_link(lk); /* selected terminal */
        }
    }
}

static inline void lk_lsta_lslr_determine_terminal(lk_t *lk)
{
    if ( lk->statem.lsta_state == LK_STATE_IDLE ) {
        lk->statem.activation  = 0;
        lk->statem.restoration = 1;
        if ( 0 ) /* any terminals idle */ {
            /* select terminal */
        } else
        if ( 1 ) /* any terminals available */ {
            if ( lk->statem.activation  ) lk_lsla_lsta_no_terminal(lk);
            if ( lk->statem.restoration ) lk_lslr_lsta_no_terminal(lk);
        } else {
            /* select terminal */
            lk->statem.lsta_state = LK_STATE_WAIT;
            lk_lsac_lsta_deactivate_link(lk); /* selected terminal */
        }
    }
}

static inline void lk_lsta_lsld_terminal_idle(lk_t *lk)
{
    switch ( lk->statem.lsta_state ) {
        case LK_STATE_IDLE:
            lk->statem.terminal_idle = 1;
            break;
        case LK_STATE_WAIT:
            if ( lk->statem.activation  ) lk_lsla_lsta_terminal(lk);
            if ( lk->statem.restoration ) lk_lslr_lsta_terminal(lk);
            break;
    }
}

static inline void lk_lsta_lsac_terminal_available(lk_t *lk)
{
    lk->statem.terminal_available = 1;
}

#endif  __SLS_LSTA_H__

