1 /************************************************************************
2 * RSTP library - Rapid Spanning Tree (802.1t, 802.1w)
3 * Copyright (C) 2001-2003 Optical Access
6 * This file is part of RSTP library.
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
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.
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
21 **********************************************************************/
23 /* Generic (abstract) state machine : 17.13, 17.14 */
27 #include "stp_vectors.h"
34 STP_state_mach_create (void (*concreteEnterState
) (STATE_MACH_T
*),
35 Bool (*concreteCheckCondition
) (STATE_MACH_T
*),
36 char *(*concreteGetStatName
) (int),
37 void *owner
, char *name
)
41 STP_MALLOC(this, STATE_MACH_T
, "state machine");
44 this->name
= (char*) strdup (name
);
45 this->changeState
= False
;
48 this->ignoreHop2State
= BEGIN
;
50 this->concreteEnterState
= concreteEnterState
;
51 this->concreteCheckCondition
= concreteCheckCondition
;
52 this->concreteGetStatName
= concreteGetStatName
;
53 this->owner
.owner
= owner
;
59 STP_state_mach_delete (STATE_MACH_T
*this)
62 STP_FREE(this, "state machine");
66 STP_check_condition (STATE_MACH_T
* this)
70 bret
= (*(this->concreteCheckCondition
)) (this);
72 this->changeState
= True
;
79 STP_change_state (STATE_MACH_T
* this)
81 register int number_of_loops
;
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);
90 return number_of_loops
;
94 STP_hop_2_state (STATE_MACH_T
* this, unsigned int new_state
)
97 switch (this->debug
) {
100 if (new_state
== this->State
|| new_state
== this->ignoreHop2State
) break;
101 stp_trace ("%-8s(%s-%s): %s=>%s",
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
));
109 if (new_state
== this->State
) break;
110 stp_trace ("%s(%s): %s=>%s",
112 *this->owner
.stpm
->name
? this->owner
.stpm
->name
: "Glbl",
113 (*(this->concreteGetStatName
)) (this->State
),
114 (*(this->concreteGetStatName
)) (new_state
));
119 this->State
= new_state
;
120 this->changeState
= True
;