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 *
STP_state_mach_create(void (* concreteEnterState)(STATE_MACH_T *),Bool (* concreteCheckCondition)(STATE_MACH_T *),char * (* concreteGetStatName)(int),void * owner,char * name)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
STP_state_mach_delete(STATE_MACH_T * this)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
STP_check_condition(STATE_MACH_T * this)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
STP_change_state(STATE_MACH_T * this)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
STP_hop_2_state(STATE_MACH_T * this,unsigned int new_state)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