#ifndef CLICK_SPANTREE_HH
#define CLICK_SPANTREE_HH
#include <click/element.hh>
#include "bridgemessage.hh"
#include <click/timer.hh>
CLICK_DECLS
class Suppressor;
class EtherSwitch;

class EtherSpanTree : public Element {
  
public:
  EtherSpanTree();
  ~EtherSpanTree();
  
  const char *class_name() const		{ return "EtherSpanTree"; }
  const char *port_count() const		{ return "-/="; }
  const char *processing() const		{ return "h/h"; }
  
  int configure(Vector<String> &, ErrorHandler *);
  int initialize(ErrorHandler *);

  static String read_msgs(Element* f, void *);
  void add_handlers();
  
  
  void periodic();
  
  bool expire();
  void find_best();
  void find_tree();		// Returns true iff there is a change
  
  void push(int port, Packet* p);
  Packet* generate_packet(int output);
  
private:
  Suppressor* _input_sup;
  Suppressor* _output_sup;
  EtherSwitch* _switch;
  Timestamp* _topology_change;	// If set, tc should be sent with messages.
  bool _send_tc_msg;		// If true, tcm should be sent to root port.
  
  uint64_t _bridge_id;		// Should be 48 bits
  
  uint16_t _bridge_priority;	// High == unlikely to become the root node
  uint16_t _long_cache_timeout; // in seconds
  
  uint8_t _addr[6];
  
  BridgeMessage _best;
  

  // Do not change the order of the PortState enum tags.  (see set_state())
  enum PortState {BLOCK, LISTEN, LEARN, FORWARD};
  struct PortInfo {
    PortState state;
    Timestamp since;		// When the port entered the state
    bool needs_tca;
    BridgeMessage msg;
    PortInfo() { state = BLOCK; needs_tca = false; }
  };
  
  bool set_state(int i, PortState state); // Only expects BLOCK or FORWARD

  Vector<PortInfo> _port;

  Timer _hello_timer;
  static void hello_hook(Timer *, void *);

};

CLICK_ENDDECLS
#endif


syntax highlighted by Code2HTML, v. 0.9.1