⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ettstat.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * John Bicket * * Copyright (c) 1999-2003 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include <click/confparse.hh>#include <clicknet/ether.h>#include <click/error.hh>#include <click/glue.hh>#include <click/timer.hh>#include <click/straccum.hh>#include "ettstat.hh"#include "ettmetric.hh"#include "txcountmetric.hh"#include <clicknet/wifi.h>#include <elements/wifi/availablerates.hh>#include <elements/wifi/netcoding/guessmanager.hh>CLICK_DECLS// packet data should be 4 byte aligned                                         #define ASSERT_ALIGNED(p) assert(((unsigned int)(p) % 4) == 0)#define min(x,y)      ((x)<(y) ? (x) : (y))#define max(x,y)      ((x)>(y) ? (x) : (y))enum {  H_RESET,  H_BCAST_STATS,  H_BAD_VERSION,  H_IP,  H_TAU,  H_PERIOD,  H_PROBES,};static String ETTStat_read_param(Element *e, void *thunk){  ETTStat *td = (ETTStat *)e;    switch ((uintptr_t) thunk) {    case H_BCAST_STATS: return td->read_bcast_stats();    case H_BAD_VERSION: return td->bad_nodes();    case H_IP: return td->_ip.s() + "\n";    case H_TAU: return String(td->_tau) + "\n";    case H_PERIOD: return String(td->_period) + "\n";    case H_PROBES: {      StringAccum sa;      for(int x = 0; x < td->_ads_rs.size(); x++) {	sa << td->_ads_rs[x]._rate << " " << td->_ads_rs[x]._size << " ";      }      return sa.take_string() + "\n";    }    default:      return String() + "\n";    }}static int ETTStat_write_param(const String &in_s, Element *e, void *vparam,		      ErrorHandler *errh){  ETTStat *f = (ETTStat *)e;  String s = cp_uncomment(in_s);  switch((int)vparam) {  case H_RESET: {    //reset    f->reset();    break;  }  case H_TAU: {    unsigned m;    if (!cp_unsigned(s, &m))       return errh->error("tau parameter must be unsigned");    f->_tau = m;    f->reset();  }  case H_PERIOD: {    unsigned m;    if (!cp_unsigned(s, &m))       return errh->error("period parameter must be unsigned");    f->_period = m;    f->reset();  }  case H_PROBES: {    Vector<RateSize> ads_rs;    Vector<String> a;    cp_spacevec(s, a);    if (a.size() % 2 != 0) {      return errh->error("must provide even number of numbers\n");    }  for (int x = 0; x < a.size() - 1; x += 2) {    int rate;    int size;    if (!cp_integer(a[x], &rate)) {      return errh->error("invalid PROBES rate value\n");    }    if (!cp_integer(a[x + 1], &size)) {      return errh->error("invalid PROBES size value\n");    }    ads_rs.push_back(RateSize(rate, size));  }  if (!ads_rs.size()) {    return errh->error("no PROBES provided\n");  }  f->_ads_rs = ads_rs;  }          }  return 0;}ETTStat::ETTStat()  : _tau(10000),     _period(1000),     _sent(0),    _ett_metric(0),    _etx_metric(0),    _arp_table(0),    _next_neighbor_to_ad(0),    _timer(this),    _ads_rs_index(0),    _rtable(0){  add_input();}ETTStat::~ETTStat(){}voidETTStat::notify_noutputs(int n) {  set_noutputs(n > 0 ? 1 : 0);  }//1. configure//2. initialize//3. take_stateintETTStat::configure(Vector<String> &conf, ErrorHandler *errh){  String probes;  int res = cp_va_parse(conf, this, errh,			cpKeywords,			"ETHTYPE", cpUnsigned, "Ethernet encapsulation type", &_et,			"IP", cpIPAddress, "IP address", &_ip,			"ETH", cpEtherAddress, "Source Ethernet address", &_eth,			"PERIOD", cpUnsigned, "Probe broadcast period (msecs)", &_period,			"TAU", cpUnsigned, "Loss-rate averaging period (msecs)", &_tau,			"ETT", cpElement, "ETT Metric element", &_ett_metric,			"ETX", cpElement, "ETX Metric element", &_etx_metric,			"ARP", cpElement, "ARPTable element", &_arp_table,			"PROBES", cpString, "PROBES", &probes,			"RT", cpElement, "AvailabeRates", &_rtable,      "GUESSMGR", cpElement, "GuessManager element", &_guessmgr,			cpEnd);  if (res < 0)    return res;  if ((res = ETTStat_write_param(probes, this, (void *) H_PROBES, errh)) < 0) {  return res;  }  if (!_et) {    return errh->error("Must specify ETHTYPE");  }  if (!_ip) {    return errh->error("Invalid IPAddress specified\n");  }  if (!_eth) {    return errh->error("Invalid EtherAddress specified\n");  }  if (_ett_metric && _ett_metric->cast("ETTMetric") == 0) {    return errh->error("ETTMetric element is not a ETTMetric");  }  if (_etx_metric && _etx_metric->cast("TXCountMetric") == 0) {    return errh->error("ETXMetric element is not a ETXMetric");  }  if (_rtable && _rtable->cast("AvailableRates") == 0) {    return errh->error("RT element is not a AvailableRates");  }  if (_arp_table && _arp_table->cast("ARPTable") == 0) {    return errh->error("ARPTable element is not a ARPTable");  }  if (_guessmgr && _guessmgr->cast("GuessManager") == 0) {    return errh->error("GUESSMGR element is not a GuessManager");  }  return res;}void add_jitter(unsigned int max_jitter, Timestamp *t) {  unsigned j = (unsigned) (random() % (max_jitter + 1));  if (random() & 1) {      *t += Timestamp::make_msec(j);  } else {      *t -= Timestamp::make_msec(j);  }  return;}voidETTStat::run_timer(){	int p = _period / _ads_rs.size();	unsigned max_jitter = p / 10;		send_probe();		_next += Timestamp::make_msec(p);	add_jitter(max_jitter, &_next);	_timer.schedule_at(_next);}voidETTStat::take_state(Element *e, ErrorHandler *errh){  /*    * take_state gets called after    * --configure   * --initialize   * so we may need to unschedule probe timers   * and sync them up so the rates don't get    * screwed up.  */  ETTStat *q = (ETTStat *)e->cast("ETTStat");  if (!q) {    errh->error("Couldn't cast old ETTStat");    return;  }    _neighbors = q->_neighbors;  _bcast_stats = q->_bcast_stats;  _rev_arp = q->_rev_arp;  _sent = q->_sent;  _start = q->_start;  if (Timestamp::now() < q->_next) {    _timer.unschedule();    _timer.schedule_at(q->_next);    _next = q->_next;  }  }void ETTStat::update_link(IPAddress from, IPAddress to, Vector<RateSize> rs, Vector<int> fwd, Vector<int> rev, uint32_t seq){  if (_ett_metric) {    _ett_metric->update_link(from, to, rs, fwd, rev, seq);  }  if (_etx_metric) {    _etx_metric->update_link(from, to, rs, fwd, rev, seq);  }    if (_guessmgr) {    EtherAddress src = _arp_table->lookup(from);    if (from == _ip) {      src = EtherAddress(_eth.data());    }    EtherAddress dst = _arp_table->lookup(to);       if (to == _ip) {      dst = EtherAddress(_eth.data());    }    if ((src != _arp_table->_bcast) && (dst != _arp_table->_bcast)) {      _guessmgr->update_del_prob(src, dst, rs, fwd, rev, seq);    }  }}  voidETTStat::send_probe() {  if (!_ads_rs.size()) {    click_chatter("%{element} :: %s no probes to send at\n",		  this,		  __func__);    return;  }  int size = _ads_rs[_ads_rs_index]._size;  int rate = _ads_rs[_ads_rs_index]._rate;  _ads_rs_index = (_ads_rs_index + 1) % _ads_rs.size();  _sent++;  unsigned min_packet_sz = sizeof(click_ether) + sizeof(struct link_probe);  if ((unsigned) size < min_packet_sz) {    click_chatter("%{element} cannot send packet size %d: min is %d\n",		  this, 		  size,		  min_packet_sz);    return;  }  WritablePacket *p = Packet::make(size + 2); // +2 for alignment  if (p == 0) {    click_chatter("ETTStat %s: cannot make packet!", id().cc());    return;  }  ASSERT_ALIGNED(p->data());  p->pull(2);  memset(p->data(), 0, p->length());  p->set_timestamp_anno(Timestamp::now());    // fill in ethernet header   click_ether *eh = (click_ether *) p->data();  memset(eh->ether_dhost, 0xff, 6); // broadcast  eh->ether_type = htons(_et);  memcpy(eh->ether_shost, _eth.data(), 6);  link_probe *lp = (struct link_probe *) (p->data() + sizeof(click_ether));  lp->_version = _ett_version;  lp->_ip = _ip.addr();  lp->_seq = p->timestamp_anno().sec();  lp->_period = _period;  lp->_tau = _tau;  lp->_sent = _sent;  lp->_flags = 0;  lp->_rate = rate;  lp->_size = size;  lp->_num_probes = _ads_rs.size();    uint8_t *ptr =  (uint8_t *) (lp + 1);  uint8_t *end  = (uint8_t *) p->data() + p->length();    Vector<int> rates;  if (_rtable) {    rates = _rtable->lookup(_eth);  }  if (rates.size() && 1 + ptr + rates.size() < end) {    ptr[0] = rates.size();    ptr++;    int x = 0;    while (ptr < end && x < rates.size()) {	ptr[x] = rates[x];	x++;    }    ptr += rates.size();    lp->_flags |= PROBE_AVAILABLE_RATES;  }  int num_entries = 0;  while (ptr < end && num_entries < _neighbors.size()) {    _next_neighbor_to_ad = (_next_neighbor_to_ad + 1) % _neighbors.size();    if (_next_neighbor_to_ad >= _neighbors.size()) {      break;    }    probe_list_t *probe = _bcast_stats.findp(_neighbors[_next_neighbor_to_ad]);    if (!probe) {      click_chatter("%{element}: lookup for %s, %d failed in ad \n", 		    this,		    _neighbors[_next_neighbor_to_ad].s().cc(),		    _next_neighbor_to_ad);    } else {      int size = probe->_probe_types.size()*sizeof(link_info) + sizeof(link_entry);      if (ptr + size > end) {	break;      }      num_entries++;      link_entry *entry = (struct link_entry *)(ptr);       entry->_ip = probe->_ip;      entry->_seq = probe->_seq;	      if ((uint32_t) probe->_ip > (uint32_t) _ip) {	entry->_seq = lp->_seq;      }      entry->_num_rates = probe->_probe_types.size();      ptr += sizeof(link_entry);      Vector<RateSize> rates;      Vector<int> fwd;      Vector<int> rev;      for (int x = 0; x < probe->_probe_types.size(); x++) {	RateSize rs = probe->_probe_types[x];	link_info *lnfo = (struct link_info *) (ptr + x*sizeof(link_info));	lnfo->_size = rs._size;	lnfo->_rate = rs._rate;	lnfo->_fwd = probe->fwd_rate(rs._rate, rs._size);	lnfo->_rev = probe->rev_rate(_start, rs._rate, rs._size);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -