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

📄 pep.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
字号:
/* * pep.{cc,hh} -- Grid Position Estimation Protocol * Robert Morris * * Copyright (c) 1999-2000 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 "pep.hh"#include "amoeba.hh"#include <click/confparse.hh>#include <click/error.hh>#include "grid.hh"#include <math.h>CLICK_DECLSPEP::PEP()  : _timer(this){  _fixed = 0;  _seq = 1;  _debug = false;}PEP::~PEP(){}void *PEP::cast(const char *name){  if(strcmp(name, "GridLocationInfo") == 0)    return(this);  return(GridLocationInfo::cast(name));}intPEP::configure(Vector<String> &conf, ErrorHandler *errh){  int lat_int = 0, lon_int = 0;  bool fixed = false;  int res = cp_va_kparse(conf, this, errh,			 "IP", cpkP+cpkM, cpIPAddress, &_my_ip,			 "FIXED", cpkP, cpBool, &fixed,			 "LATITUDE", cpkP, cpReal10, 5, &lat_int,			 "LONGITUDE", cpkP, cpReal10, 5, &lon_int,			 cpEnd);  if(res < 0)    return(res);  if(fixed){    float lat = ((float) lat_int) / 100000.0f;    float lon = ((float) lon_int) / 100000.0f;    if (lat > 90 || lat < -90)      return errh->error("%s: latitude must be between +/- 90 degrees",                         name().c_str());    if (lon > 180 || lon < -180)      return errh->error("%s: longitude must be between +/- 180 degrees",                         name().c_str());    _lat = lat;    _lon = lon;    _fixed = true;  }  return(0);}intPEP::initialize(ErrorHandler *){  _timer.initialize(this);  _timer.schedule_after_msec(pep_update * 1000);  return 0;}voidPEP::run_timer(Timer *){  purge_old();  output(0).push(make_PEP());  _timer.schedule_after_msec(click_random() % (pep_update * 1000 * 2));}voidPEP::purge_old(){  Timestamp tv = Timestamp::now();  int i = 0;  int j;  for(j = 0; j < _entries.size(); j++){    if(tv.sec() - _entries[j]._when.sec() <= pep_purge){      _entries[i++] = _entries[j];    } else {      if(_debug)        click_chatter("PEP %s %s: purging old entry for %s (%d %d %d)",                      name().c_str(),                      _my_ip.unparse().c_str(),                      IPAddress(_entries[j]._fix.fix_id).unparse().c_str(),                      (int) _entries[j]._when.sec(),                      (int) tv.sec(),                      pep_purge);    }  }  static Entry dud;  _entries.resize(i, dud);}voidPEP::sort_entries(){  int n = _entries.size();  int i, j;  for(i = 0; i < n; i++){    int h = _entries[i]._fix.fix_hops;    for(j = i + 1; j < n; j++){      if(_entries[j]._fix.fix_hops < h){        Entry tmp = _entries[i];        _entries[i] = _entries[j];        _entries[j] = tmp;      }    }  }}// Are we allowed to send a particular update?boolPEP::sendable(Entry e){  Timestamp tv = Timestamp::now();  if(e._when.sec() + pep_stale > tv.sec() &&     e._fix.fix_hops < pep_max_hops){    return(true);  }  return(false);}voidPEP::externalize(pep_fix *fp){  fp->fix_seq = htonl(fp->fix_seq);  fp->fix_hops = htonl(fp->fix_hops);}voidPEP::internalize(pep_fix *fp){  fp->fix_seq = ntohl(fp->fix_seq);  fp->fix_hops = ntohl(fp->fix_hops);}Packet *PEP::make_PEP(){  WritablePacket *p = Packet::make(sizeof(pep_proto));  memset(p->data(), 0, p->length());  pep_proto *pp = (pep_proto *) p->data();  pp->id = _my_ip.addr();  int nf = 0;  if(_fixed){    pep_fix *f = pp->fixes + nf;    nf++;    f->fix_id = _my_ip.addr();    f->fix_seq = htonl(_seq++);    f->fix_loc = grid_location(_lat, _lon);    f->fix_hops = htonl(0);  }  sort_entries();  int i;  for(i = 0; i < _entries.size() && nf < pep_proto_fixes; i++){    if(sendable(_entries[i])){      pp->fixes[nf] = _entries[i]._fix;      pp->fixes[nf].fix_hops += 1;      externalize(&(pp->fixes[nf]));      nf++;    }  }  pp->n_fixes = htonl(nf);  return p;}intPEP::findEntry(unsigned id, bool create){  int i;  for(i = 0; i < _entries.size(); i++)    if(_entries[i]._fix.fix_id == id)      return(i);  if(create){    if(_debug)      click_chatter("PEP %s %s: new entry for %s",                    this->name().c_str(),                    _my_ip.unparse().c_str(),                    IPAddress(id).unparse().c_str());    i = _entries.size();    static Entry e;    e._fix.fix_id = id;    e._fix.fix_hops = -1;    e._fix.fix_seq = -1;    _entries.push_back(e);    assert(_entries.size() == i+1 && _entries[i]._fix.fix_id == id);    return(i);  } else {    return(-1);  }}Packet *PEP::simple_action(Packet *p){  int nf;  pep_proto *pp;  Timestamp tv = Timestamp::now();  if(p->length() != sizeof(pep_proto)){    click_chatter("PEP: bad size packet (%d bytes)", p->length());    goto out;  }  pp = (pep_proto *) p->data();  nf = ntohl(pp->n_fixes);  if(nf < 0 || (const u_char*)&pp->fixes[nf] > p->data()+p->length()){    click_chatter("PEP: bad n_fixes %d", nf);    goto out;  }  int i;  for(i = 0; i < nf && i < pep_proto_fixes; i++){    pep_fix f = pp->fixes[i];    internalize(&f);    if(f.fix_id == _my_ip.addr())      continue;    int j = findEntry(f.fix_id, true);    if(j < 0)      continue;    int os = _entries[j]._fix.fix_seq;    int oh = _entries[j]._fix.fix_hops;    if(f.fix_seq > os ||       (f.fix_seq == os && f.fix_hops < oh)){      _entries[j]._fix = f;      _entries[j]._when = tv;      if(_debug && f.fix_hops != oh)        click_chatter("PEP %s %s: updating %s, seq %d -> %d, hops %d -> %d, my pos %s",                      name().c_str(),                      _my_ip.unparse().c_str(),                      IPAddress(f.fix_id).unparse().c_str(),                      os,                      f.fix_seq,                      oh,                      f.fix_hops,                      get_current_location().s().c_str());    }  } out:  p->kill();  return(0);}// Actually guess where we are.grid_locationPEP::algorithm1(){  double lat = 0, lon = 0;  double weight = 0;  int i;  Timestamp now = Timestamp::now();  for(i = 0; i < _entries.size(); i++){    if(now.sec() - _entries[i]._when.sec() < pep_stale){      double w = 1.0 / (_entries[i]._fix.fix_hops + 1);      lat += w * _entries[i]._fix.fix_loc.lat();      lon += w * _entries[i]._fix.fix_loc.lon();      weight += w;    }  }  return(grid_location(lat / weight, lon / weight));}class PEPAmoeba : public Amoeba {public:  PEPAmoeba () : Amoeba(2) { }  double fn(double a[]);  int _n;  double _x[20];  double _y[20];  double _d[20];};doublePEPAmoeba::fn(double a[]){  double x = a[0];  double y = a[1];  double d = 0;  int i;  for(i = 0; i < _n; i++){    double dx = x - _x[i];    double dy = y - _y[i];    double dd = _d[i] - sqrt(dx*dx + dy*dy);    dd = dd * dd;    d += dd;  }  return(d);}grid_locationPEP::algorithm2(){  PEPAmoeba a;  int i;  Timestamp now = Timestamp::now();  a._n = 0;  for(i = 0; i < _entries.size() && a._n < 5; i++){    if(now.sec() - _entries[i]._when.sec() < pep_stale){      a._x[a._n] = _entries[i]._fix.fix_loc.lat();      a._y[a._n] = _entries[i]._fix.fix_loc.lat();      a._d[a._n] = _entries[i]._fix.fix_hops * 0.002; // XXX 250 meters?  should be fix_hops + 1??      a._n += 1;    }  }  double pts[2];  a.minimize(pts);  return(grid_location(pts[0], pts[1]));}grid_locationPEP::get_current_location(){  if(_fixed)    return(grid_location(_lat, _lon));  if(_entries.size() < 1)    return(grid_location(0.0, 0.0));  return(algorithm1());}static Stringpep_read_handler(Element *f, void *){  PEP *l = (PEP *) f;  return(l->s());}StringPEP::s(){  String s;  int i, n;  Timestamp now = Timestamp::now();  if(_fixed){    s = _my_ip.unparse() + " " +      grid_location(_lat, _lon).s() + "\n";  } else {    s = _my_ip.unparse() + "\n";  }  s += get_current_location().s() + "\n";  n = _entries.size();  for(i = 0; i < n; i++){    pep_fix f = _entries[i]._fix;    char buf[512];    snprintf(buf, sizeof(buf), "%s seq=%d %s hops=%d age=%d\n",             IPAddress(f.fix_id).unparse().c_str(),             f.fix_seq,             f.fix_loc.s().c_str(),             f.fix_hops,             (int)(now.sec() - _entries[i]._when.sec()));    s += buf;  }  return s;}voidPEP::add_handlers(){  add_read_handler("status", pep_read_handler, (void *) 0);}CLICK_ENDDECLSELEMENT_REQUIRES(GridLocationInfo Amoeba)EXPORT_ELEMENT(PEP)

⌨️ 快捷键说明

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