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