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

 @(#) $Id: mtp_rsrt.h,v 0.7.2.2 2001/02/03 05:48:41 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:41 $ by $Author: brian $

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

#ifndef __MTP_RSRT_H__
#define __MTP_RSRT_H__

/*
 *  Referenced declarations.
 */

static inline void rs_hmrt_signalling_route_set_test(rs_t *rs);

static inline void rs_rtac_send_transfer_allowed_message(rs_t *rs);

static inline void rs_rtpc_send_transfer_prohibited_message(rs_t *rs);

static inline void rs_rtrc_send_transfer_restricted_message(rs_t *rs);

static inline void rs_tsrc_accessibility_data_request(rs_t *rs);

/*
 *  Forward declarations.
 */

static inline void rs_t10_timeout(rs_t *rs);

static inline void rs_rsrt_accessibility_data(rs_t *rs);
static inline void rs_rsrt_adjacent_sp_restarted(rs_t *rs);
static inline void rs_rsrt_adjacent_sp_restarting(rs_t *rs);
static inline void rs_rsrt_restart_begins(rs_t *rs);
static inline void rs_rsrt_restart_ends(rs_t *rs);
static inline void rs_rsrt_signalling_route_available(rs_t *rs);
static inline void rs_rsrt_signalling_route_set_test(rs_t *rs);
static inline void rs_rsrt_start_route_set_test(rs_t *rs);
static inline void rs_rsrt_start_route_set_test_tfp(rs_t *rs);
static inline void rs_rsrt_start_route_set_test_tfr(rs_t *rs);

/*
 *  Signalling Route Management (SRM)
 *  Signalling Route Set Test Control (RSRT)
 *  Figure 46/Q.704
 */

static inline void rs_t10_timeout(rs_t *rs)
{
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_WAIT:
            rs_hmrt_signalling_route_set_test(rs);
            rs_timer_start(t10);
            break;
    }
}

static inline void rs_rsrt_start_route_set_test_tfr(rs_t *rs) /* TFR received */
{
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_IDLE:
        case RS_STATE_WAIT:
            /* Set route set test for restricted destination */
            rs_timer_start(t10);
            rs->statem.rsrt_state = RS_STATE_WAIT;
            break;
    }
}

static inline void rs_rsrt_start_route_set_test_tfp(rs_t *rs) /* TFP received */
{
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_IDLE:
        case RS_STATE_WAIT:
            /* Set route set test for prohibited destination */
            rs_timer_start(t10);
            rs->statem.rsrt_state = RS_STATE_WAIT;
            break;
    }
}

static inline void rs_rsrt_start_route_set_test(rs_t *rs)
{
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_IDLE:
            rs_hmrt_signalling_route_set_test(rs); /* Referred to concerned destination */
            break;
    }
}

static inline void rs_rsrt_signalling_route_available(rs_t *rs)
{
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_WAIT:
            rs_timer_stop(t10);
            rs->statem.rsrt_state = RS_STATE_IDLE;
            break;
    }
}

static inline void rs_rsrt_signalling_route_set_test(rs_t *rs)
{
    /* originated by STP Y from renote level 3 */
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_IDLE:
            if ( !rs->statem.own_sp_restarting ) {
                rs_tsrc_accessibility_data_request(rs); /* for the concerned destination */
                rs->statem.rsrt_state = RS_STATE_WAIT_FOR_DATA;
            }
            break;
    }
}

static inline void rs_rsrt_accessibility_data(rs_t *rs)
{
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_WAIT_FOR_DATA:
            rs->statem.rsrt_state = RS_STATE_IDLE;
            if ( rs->statem.data_ok )
                /* Is accessibility data the same as in route set test message? */
                break;
            if ( !rs->statem.destination_accessible ||
                    rs->statem.only_via_y /* desintation accessible only via STP Y */ ) {
                rs_rtpc_send_transfer_prohibited_message(rs);
                break;
            }
            if ( rs->statem.not_via_y_or_fpls ) {
                /* has a transfer restricted message already been sent for
                 * this destination to any SP including possibly Y? */
                rs_rtrc_send_transfer_restricted_message(rs);
                break;
            }
            rs_rtac_send_transfer_allowed_message(rs);
            break;
    }
}

static inline void rs_rsrt_adjacent_sp_restarting(rs_t *rs)
{
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_IDLE:
            rs->statem.adjacent_sp_restarting = 1;
            break;
        case RS_STATE_WAIT:
            /* cancel all marks */
            rs->statem.own_sp_restarting = 0;
            rs->statem.adjacent_sp_restarting = 1;
            rs->statem.rsrt_state = RS_STATE_IDLE;
            break;
    }
}

static inline void rs_rsrt_restart_begins(rs_t *rs)
{
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_IDLE:
            rs->statem.own_sp_restarting = 1;
            break;
        case RS_STATE_WAIT:
            /* cancel all marks */
            rs->statem.adjacent_sp_restarting = 0;
            rs->statem.own_sp_restarting = 1;
            rs->statem.rsrt_state = RS_STATE_IDLE;
            break;
    }
}

static inline void rs_rsrt_adjacent_sp_restarted(rs_t *rs)
{
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_IDLE:
            rs->statem.own_sp_restarting = 0;
            break;
    }
}

static inline void rs_rsrt_restart_ends(rs_t *rs)
{
    switch ( rs->statem.rsrt_state ) {
        case RS_STATE_IDLE:
            rs->statem.own_sp_restarting = 0;
            break;
    }
}

#endif  __MTP_RSRT_H__

