rstplib源码分析---快速生成树之通用状态机

本文详细介绍了rstplib中用于快速生成树(RSTP)的通用状态机的源码,包括数据结构定义、核心宏、创建和删除状态机的函数,以及状态检查和更新的实现。通过分析,揭示了状态机如何在网桥和端口之间工作,并维护其状态变化。
摘要由CSDN通过智能技术生成

1 源码

   rstplib.1.1.02/statmch.c,statmch.h

2 功能

   提供了快速生成树中所有状态机的一个抽象,类似于面向对象编程中的基类。

3 代码简析

3.1 数据结构

/* 通用状态机 */

typedef struct state_mach_t {

  struct state_mach_t* next; // 下一状态机

  Bool          changeState; // 状态变化标志

  unsigned int  State; // 当前状态

  void          (* concreteEnterState) (struct state_mach_t * ); // 执行进入某状态后的固定动作

  Bool          (* concreteCheckCondition) (struct state_mach_t * ); // 检查状态倒换条件并完成状态倒换

  union {

    struct stpm_t* stpm; // 指向本状态机所属网桥

    struct port_t* port; // 指向本状态机所属端口

    void  * owner; // 指向本状态机的创建者,可能是某端口,也可能是某网桥

  } owner;

} STATE_MACH_T;

3.2 核心宏

/* 将某具体状态机(由WHAT填入状态机名称,加##不展开WHAT,参见《宏中"#"和"##"的用法》)添加到this下面附带的状态机链表中,其中this视此宏应用场合不同而定,可能指向端口或网桥*/

#define STP_STATE_MACH_IN_LIST(WHAT)                         /

{                                                                                          /

    STATE_MACH_T* abstr;                                                   /

    /* 创建状态机,关联执行函数、检测函数,登记状态机属主(this)*/

    abstr = STP_state_mach_create (STP_##WHAT##_enter_state,           /

                                  STP_##WHAT##_check_conditions,                          /

                                  STP_##WHAT##_get_state_name,                          /

                                  this,                                                                            /

                                  #WHAT);                                                                    /

    abstr->next = this->machines;  /

    this->machines = abstr;       / // 通过指针修改将此状态机加入状态机链表

    this->WHAT = abstr;         / // 更新this的具体状态机指针指向此状态机

}

3.3 实现

/* 创建状态机 */

STATE_MACH_T * STP_state_mach_create (void (*concreteEnterState) (STATE_MACH_T*),

                       Bool (*concreteCheckCondition) (STATE_MACH_T*),

                       char *(*concreteGetStatName) (int),

                       void *owner, char *name)

{

  STATE_MACH_T *this;

  STP_MALLOC(this, STATE_MACH_T, "state machine");  // 分配内存空间

  this->State = BEGIN;

  /* 复制状态机名称字符串,所需空间由malloc()分配且可以由free()释放 – strdup() */

  this->name = (char*) strdup (name); 

  this->changeState = False;

  /* 关联状态机对应的具体函数 */

  this->concreteEnterState = concreteEnterState;

  this->concreteCheckCondition = concreteCheckCondition;

  this->concreteGetStatName = concreteGetStatName ;

  /* 登记属主 */

  this->owner.owner = owner;

  return this;

}

/* 删除状态机 */

void STP_state_mach_delete (STATE_MACH_T *this)

{

  free (this->name); // 释放状态机名称字符串所占空间

  STP_FREE(this, "state machine"); // 释放状态机空间

}

/* 检查倒换条件 */

Bool STP_check_condition (STATE_MACH_T* this)

{

  Bool bret;

  bret = (*(this->concreteCheckCondition)) (this); // 调用具体检查倒换函数

  if (bret) {

    this->changeState = True; // 状态有变

  }

  return bret;

}

/* 状态机更新,在生成树更新函数中被调用 */

Bool STP_change_state (STATE_MACH_T* this)

{

  register int number_of_loops;

  for (number_of_loops = 0; ; number_of_loops++) {

    if (! this->changeState) return number_of_loops; // 状态无变化则返回

    (*(this->concreteEnterState)) (this); // 进入当前态,执行对应动作

    this->changeState = False; // 复位状态变化标志

    STP_check_condition (this); // 检查倒换条件并执行倒换,更新状态变化标志

  }

  return number_of_loops;

}

/* 状态机状态倒换 */

Bool STP_hop_2_state (STATE_MACH_T* this, unsigned int new_state)

{

  this->State = new_state;  // 更新状态

  this->changeState = True; // 置位状态倒换标志

  return True;

}

4 网桥、端口、状态机关系图

RSTP-generic_state_machine


转载自:http://blog.csdn.net/zhaoqiaoshi/article/details/5412807

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值