1*4eaa4710SRishi Srivatsavai /************************************************************************ 2*4eaa4710SRishi Srivatsavai * RSTP library - Rapid Spanning Tree (802.1t, 802.1w) 3*4eaa4710SRishi Srivatsavai * Copyright (C) 2001-2003 Optical Access 4*4eaa4710SRishi Srivatsavai * Author: Alex Rozin 5*4eaa4710SRishi Srivatsavai * 6*4eaa4710SRishi Srivatsavai * This file is part of RSTP library. 7*4eaa4710SRishi Srivatsavai * 8*4eaa4710SRishi Srivatsavai * RSTP library is free software; you can redistribute it and/or modify it 9*4eaa4710SRishi Srivatsavai * under the terms of the GNU Lesser General Public License as published by the 10*4eaa4710SRishi Srivatsavai * Free Software Foundation; version 2.1 11*4eaa4710SRishi Srivatsavai * 12*4eaa4710SRishi Srivatsavai * RSTP library is distributed in the hope that it will be useful, but 13*4eaa4710SRishi Srivatsavai * WITHOUT ANY WARRANTY; without even the implied warranty of 14*4eaa4710SRishi Srivatsavai * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 15*4eaa4710SRishi Srivatsavai * General Public License for more details. 16*4eaa4710SRishi Srivatsavai * 17*4eaa4710SRishi Srivatsavai * You should have received a copy of the GNU Lesser General Public License 18*4eaa4710SRishi Srivatsavai * along with RSTP library; see the file COPYING. If not, write to the Free 19*4eaa4710SRishi Srivatsavai * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20*4eaa4710SRishi Srivatsavai * 02111-1307, USA. 21*4eaa4710SRishi Srivatsavai **********************************************************************/ 22*4eaa4710SRishi Srivatsavai 23*4eaa4710SRishi Srivatsavai /* Generic (abstract) state machine : 17.13, 17.14 */ 24*4eaa4710SRishi Srivatsavai 25*4eaa4710SRishi Srivatsavai #include "base.h" 26*4eaa4710SRishi Srivatsavai #include "statmch.h" 27*4eaa4710SRishi Srivatsavai #include "stp_vectors.h" 28*4eaa4710SRishi Srivatsavai 29*4eaa4710SRishi Srivatsavai #if STP_DBG 30*4eaa4710SRishi Srivatsavai # include "stpm.h" 31*4eaa4710SRishi Srivatsavai #endif 32*4eaa4710SRishi Srivatsavai 33*4eaa4710SRishi Srivatsavai STATE_MACH_T * 34*4eaa4710SRishi Srivatsavai STP_state_mach_create (void (*concreteEnterState) (STATE_MACH_T*), 35*4eaa4710SRishi Srivatsavai Bool (*concreteCheckCondition) (STATE_MACH_T*), 36*4eaa4710SRishi Srivatsavai char *(*concreteGetStatName) (int), 37*4eaa4710SRishi Srivatsavai void *owner, char *name) 38*4eaa4710SRishi Srivatsavai { 39*4eaa4710SRishi Srivatsavai STATE_MACH_T *this; 40*4eaa4710SRishi Srivatsavai 41*4eaa4710SRishi Srivatsavai STP_MALLOC(this, STATE_MACH_T, "state machine"); 42*4eaa4710SRishi Srivatsavai 43*4eaa4710SRishi Srivatsavai this->State = BEGIN; 44*4eaa4710SRishi Srivatsavai this->name = (char*) strdup (name); 45*4eaa4710SRishi Srivatsavai this->changeState = False; 46*4eaa4710SRishi Srivatsavai #if STP_DBG 47*4eaa4710SRishi Srivatsavai this->debug = False; 48*4eaa4710SRishi Srivatsavai this->ignoreHop2State = BEGIN; 49*4eaa4710SRishi Srivatsavai #endif 50*4eaa4710SRishi Srivatsavai this->concreteEnterState = concreteEnterState; 51*4eaa4710SRishi Srivatsavai this->concreteCheckCondition = concreteCheckCondition; 52*4eaa4710SRishi Srivatsavai this->concreteGetStatName = concreteGetStatName; 53*4eaa4710SRishi Srivatsavai this->owner.owner = owner; 54*4eaa4710SRishi Srivatsavai 55*4eaa4710SRishi Srivatsavai return this; 56*4eaa4710SRishi Srivatsavai } 57*4eaa4710SRishi Srivatsavai 58*4eaa4710SRishi Srivatsavai void 59*4eaa4710SRishi Srivatsavai STP_state_mach_delete (STATE_MACH_T *this) 60*4eaa4710SRishi Srivatsavai { 61*4eaa4710SRishi Srivatsavai free (this->name); 62*4eaa4710SRishi Srivatsavai STP_FREE(this, "state machine"); 63*4eaa4710SRishi Srivatsavai } 64*4eaa4710SRishi Srivatsavai 65*4eaa4710SRishi Srivatsavai Bool 66*4eaa4710SRishi Srivatsavai STP_check_condition (STATE_MACH_T* this) 67*4eaa4710SRishi Srivatsavai { 68*4eaa4710SRishi Srivatsavai Bool bret; 69*4eaa4710SRishi Srivatsavai 70*4eaa4710SRishi Srivatsavai bret = (*(this->concreteCheckCondition)) (this); 71*4eaa4710SRishi Srivatsavai if (bret) { 72*4eaa4710SRishi Srivatsavai this->changeState = True; 73*4eaa4710SRishi Srivatsavai } 74*4eaa4710SRishi Srivatsavai 75*4eaa4710SRishi Srivatsavai return bret; 76*4eaa4710SRishi Srivatsavai } 77*4eaa4710SRishi Srivatsavai 78*4eaa4710SRishi Srivatsavai Bool 79*4eaa4710SRishi Srivatsavai STP_change_state (STATE_MACH_T* this) 80*4eaa4710SRishi Srivatsavai { 81*4eaa4710SRishi Srivatsavai register int number_of_loops; 82*4eaa4710SRishi Srivatsavai 83*4eaa4710SRishi Srivatsavai for (number_of_loops = 0; ; number_of_loops++) { 84*4eaa4710SRishi Srivatsavai if (! this->changeState) break; 85*4eaa4710SRishi Srivatsavai (*(this->concreteEnterState)) (this); 86*4eaa4710SRishi Srivatsavai this->changeState = False; 87*4eaa4710SRishi Srivatsavai (void) STP_check_condition (this); 88*4eaa4710SRishi Srivatsavai } 89*4eaa4710SRishi Srivatsavai 90*4eaa4710SRishi Srivatsavai return number_of_loops; 91*4eaa4710SRishi Srivatsavai } 92*4eaa4710SRishi Srivatsavai 93*4eaa4710SRishi Srivatsavai Bool 94*4eaa4710SRishi Srivatsavai STP_hop_2_state (STATE_MACH_T* this, unsigned int new_state) 95*4eaa4710SRishi Srivatsavai { 96*4eaa4710SRishi Srivatsavai #ifdef STP_DBG 97*4eaa4710SRishi Srivatsavai switch (this->debug) { 98*4eaa4710SRishi Srivatsavai case 0: break; 99*4eaa4710SRishi Srivatsavai case 1: 100*4eaa4710SRishi Srivatsavai if (new_state == this->State || new_state == this->ignoreHop2State) break; 101*4eaa4710SRishi Srivatsavai stp_trace ("%-8s(%s-%s): %s=>%s", 102*4eaa4710SRishi Srivatsavai this->name, 103*4eaa4710SRishi Srivatsavai *this->owner.port->owner->name ? this->owner.port->owner->name : "Glbl", 104*4eaa4710SRishi Srivatsavai this->owner.port->port_name, 105*4eaa4710SRishi Srivatsavai (*(this->concreteGetStatName)) (this->State), 106*4eaa4710SRishi Srivatsavai (*(this->concreteGetStatName)) (new_state)); 107*4eaa4710SRishi Srivatsavai break; 108*4eaa4710SRishi Srivatsavai case 2: 109*4eaa4710SRishi Srivatsavai if (new_state == this->State) break; 110*4eaa4710SRishi Srivatsavai stp_trace ("%s(%s): %s=>%s", 111*4eaa4710SRishi Srivatsavai this->name, 112*4eaa4710SRishi Srivatsavai *this->owner.stpm->name ? this->owner.stpm->name : "Glbl", 113*4eaa4710SRishi Srivatsavai (*(this->concreteGetStatName)) (this->State), 114*4eaa4710SRishi Srivatsavai (*(this->concreteGetStatName)) (new_state)); 115*4eaa4710SRishi Srivatsavai break; 116*4eaa4710SRishi Srivatsavai } 117*4eaa4710SRishi Srivatsavai #endif 118*4eaa4710SRishi Srivatsavai 119*4eaa4710SRishi Srivatsavai this->State = new_state; 120*4eaa4710SRishi Srivatsavai this->changeState = True; 121*4eaa4710SRishi Srivatsavai return True; 122*4eaa4710SRishi Srivatsavai } 123*4eaa4710SRishi Srivatsavai 124