]>
Commit | Line | Data |
---|---|---|
ad02a0eb SH |
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 | ||
28 | #if STP_DBG | |
29 | # include "stpm.h" | |
30 | #endif | |
31 | ||
32 | STATE_MACH_T * | |
33 | STP_state_mach_create (void (*concreteEnterState) (STATE_MACH_T*), | |
34 | Bool (*concreteCheckCondition) (STATE_MACH_T*), | |
35 | char *(*concreteGetStatName) (int), | |
36 | void *owner, char *name) | |
37 | { | |
38 | STATE_MACH_T *this; | |
39 | ||
40 | STP_MALLOC(this, STATE_MACH_T, "state machine"); | |
41 | ||
42 | this->State = BEGIN; | |
43 | this->name = (char*) strdup (name); | |
44 | this->changeState = False; | |
45 | #if STP_DBG | |
46 | this->debug = False; | |
47 | this->ignoreHop2State = BEGIN; | |
48 | #endif | |
49 | this->concreteEnterState = concreteEnterState; | |
50 | this->concreteCheckCondition = concreteCheckCondition; | |
51 | this->concreteGetStatName = concreteGetStatName; | |
52 | this->owner.owner = owner; | |
53 | ||
54 | return this; | |
55 | } | |
56 | ||
57 | void | |
58 | STP_state_mach_delete (STATE_MACH_T *this) | |
59 | { | |
60 | free (this->name); | |
61 | STP_FREE(this, "state machine"); | |
62 | } | |
63 | ||
64 | Bool | |
65 | STP_check_condition (STATE_MACH_T* this) | |
66 | { | |
67 | Bool bret; | |
68 | ||
69 | bret = (*(this->concreteCheckCondition)) (this); | |
70 | if (bret) { | |
71 | this->changeState = True; | |
72 | } | |
73 | ||
74 | return bret; | |
75 | } | |
76 | ||
77 | Bool | |
78 | STP_change_state (STATE_MACH_T* this) | |
79 | { | |
80 | register int number_of_loops; | |
81 | ||
82 | for (number_of_loops = 0; ; number_of_loops++) { | |
83 | if (! this->changeState) return number_of_loops; | |
84 | (*(this->concreteEnterState)) (this); | |
85 | this->changeState = False; | |
86 | STP_check_condition (this); | |
87 | } | |
88 | ||
89 | return number_of_loops; | |
90 | } | |
91 | ||
92 | Bool | |
93 | STP_hop_2_state (STATE_MACH_T* this, unsigned int new_state) | |
94 | { | |
95 | #ifdef STP_DBG | |
96 | switch (this->debug) { | |
97 | case 0: break; | |
98 | case 1: | |
99 | if (new_state == this->State || new_state == this->ignoreHop2State) break; | |
100 | stp_trace ("%-8s(%s-%s): %s=>%s", | |
101 | this->name, | |
102 | *this->owner.port->owner->name ? this->owner.port->owner->name : "Glbl", | |
103 | this->owner.port->port_name, | |
104 | (*(this->concreteGetStatName)) (this->State), | |
105 | (*(this->concreteGetStatName)) (new_state)); | |
106 | break; | |
107 | case 2: | |
108 | if (new_state == this->State) break; | |
109 | stp_trace ("%s(%s): %s=>%s", | |
110 | this->name, | |
111 | *this->owner.stpm->name ? this->owner.stpm->name : "Glbl", | |
112 | (*(this->concreteGetStatName)) (this->State), | |
113 | (*(this->concreteGetStatName)) (new_state)); | |
114 | break; | |
115 | } | |
116 | #endif | |
117 | ||
118 | this->State = new_state; | |
119 | this->changeState = True; | |
120 | return True; | |
121 | } | |
122 |