📄 spanagent.cc
字号:
_is_tentative = false;#if TRACE_ANNOUNCE > 1 fprintf(stderr, "# %f: %d coordinator not tentative\n", NOW, _my_id);#endif return true; } } else {#if TRACE_ANNOUNCE > 1 fprintf(stderr, "# %f: %d coordinator must stay on\n", NOW, _my_id);#endif _withdraw_meter = 0; if (_is_tentative) { _is_tentative = false; return true; } } }#endif return false;}boolSpanAgent::check_withdraw(bool force_withdraw){ #if(PROTOCOL==CLEAR) if (check_coverage()) { return false; } return true;#elif(PROTOCOL==SPAN_CLEAR) if (check_coverage()) { return false; } // return true; // fprintf(stderr,"# %d is fully covered\n", _my_id);#endif bool withdraw = true; LLIterator *ni = _neighbors.neighbors(); NeighborTable::Neighbor *n = (NeighborTable::Neighbor*)ni->peek(); while (n && withdraw) { if (n->id == _my_id) { n = (NeighborTable::Neighbor*)ni->next(); continue; } LLIterator *ni2 = _neighbors.neighbors(); NeighborTable::Neighbor *n2 = (NeighborTable::Neighbor*)ni2->peek(); while(n2 && withdraw) { int joint; if ((joint = _neighbors.share_coordinator(n->id, n2->id, _my_id))<0) { if (force_withdraw) { if ((joint = _neighbors.share_neighbor(n->id, n2->id, _my_id))<0) {#if TRACE_ANNOUNCE > 2 fprintf(stderr,"%d: %d+%d not joint, force\n",_my_id,n->id,n2->id);#endif withdraw = false; }#if TRACE_ANNOUNCE > 2 else fprintf(stderr,"%d: %d+%d by n%d\n",_my_id,n->id,n2->id,joint);#endif } else {#if TRACE_ANNOUNCE > 2 fprintf(stderr, "%d: %d+%d not joint\n", _my_id, n->id, n2->id);#endif withdraw = false; } }#if TRACE_ANNOUNCE > 3 else fprintf(stderr, "%d: %d+%d by c%d\n", _my_id, n->id, n2->id, joint);#endif n2 = (NeighborTable::Neighbor*)ni2->next(); } delete ni2; n = (NeighborTable::Neighbor*)ni->next(); } delete ni; return withdraw;}voidSpanAnnounceCoordinatorHandler::handle(Event *e){ _agent->announce_coordinator(); delete e;}voidSpanAgent::announce_coordinator(bool force){ _announce_pending = false;#if(PROTOCOL==CLEAR) if (check_coverage() > 0){#elif(PROTOCOL==SPAN_CLEAR) if (force || !_usespan || (check_coverage() > 0) || (check_announce()>0) ) {#else if (force || !_usespan || check_announce() > 0) {#endif if (_asleep && _usespan) wakeup();#if TRACE_ANNOUNCE fprintf(stderr,"# %f: %d announce coordinator (%f/%f)\n", NOW, _my_id, _energy_model->energy(),_energy_model->initialenergy());#endif _is_coordinator = true; #ifdef TWO_HOP_BEACON double x, y, z; (God::instance()->nodelist[_my_id])->getLoc(&x, &y, &z); _neighbors.add_coordinator(_my_id, _my_id, x,y,false);#else _neighbors.add_coordinator(_my_id, _my_id, false);#endif#if((PROTOCOL==SPAN_CLEAR) || (PROTOCOL==CLEAR)) if(cover_debug>2) fprintf(stderr,"# %f: %d announce coordinator done\n", NOW, _my_id);#endif NeighborTable::Neighbor *self = _neighbors.search_neighbor(_my_id); self->is_coordinator = true; self->nounce = (int)NOW; broadcast_hello(); }} #if((PROTOCOL==SPAN_CLEAR) || (PROTOCOL==CLEAR)) voidSpanAgent::force_withdraw(){#if TRACE_ANNOUNCE fprintf(stderr,"# %f: %d force to withdraw coordinator (%f/%f)\n", NOW,_my_id,_energy_model->energy(),_energy_model->initialenergy());#endif#ifndef ALL_ACTIVE _is_coordinator = false; NeighborTable::Neighbor *self = _neighbors.search_neighbor(_my_id); self->is_coordinator = false; self->nounce = (int)NOW; _neighbors.remove_coordinator(_my_id, _my_id);#endif return ;}voidSpanAgent::withdraw_coordinator(){ if (withdraw_pending_) return; withdraw_pending_ = true; double delay = jitter(withdraw_window); if(cover_debug) fprintf(stderr,"# %d withdrawing, delay is %f\n", _my_id,delay); Event *ev = new Event; Scheduler::instance().schedule (&withdraw_coordinator_handler_, ev, delay); }#elsevoid SpanAgent::withdraw_coordinator(){#if TRACE_ANNOUNCE fprintf(stderr,"# %f: %d withdraw coordinator (%f/%f)\n", NOW,_my_id,_energy_model->energy(),_energy_model->initialenergy());#endif#ifndef ALL_ACTIVE _is_coordinator = false; NeighborTable::Neighbor *self = _neighbors.search_neighbor(_my_id); self->is_coordinator = false; self->nounce = (int)NOW; _neighbors.remove_coordinator(_my_id, _my_id);#endif return ;}#endifvoidSpanAgent::forward_pkt(Packet *p){ int err = _gfrt->forward_pkt(_my_id, (hdr_ip*)p->access(_off_ip), (hdr_cmn*)p->access(off_cmn_), (hdr_span*)p->access(_off_span)); if (err == GF_TTL) drop(p, SPAN_GF_TTL); else if (err == GF_HOLE) drop(p, SPAN_GF_HOLE); else if (err == GF_FWD) send_packet(p, false); else send_packet(p, true);}voidSpanAgent::send_packet(Packet *p, bool to_coordinator){ hdr_cmn *cmnh = (hdr_cmn*)p->access(off_cmn_); hdr_span *spanh = (hdr_span*)p->access(_off_span); hdr_ip *iph = (hdr_ip*)p->access(off_ip_); add_span_hdr(p); if (_usespan) { if (cmnh->next_hop_ == iph->dst() && cmnh->next_hop_ != (int)MAC_BROADCAST) spanh->to_coordinator = true; else spanh->to_coordinator = to_coordinator; } else spanh->to_coordinator = false; cmnh->addr_type_ = AF_INET; cmnh->xmit_failure_ = tx_failure_cb; cmnh->xmit_failure_data_ = (void*) this;#if USE_ARP Scheduler::instance().schedule(_ll, p, 0);#else _mac->hdr_dst(p->access(_off_mac), cmnh->next_hop_); _mac->hdr_src(p->access(_off_mac), _my_id); Scheduler::instance().schedule(_ifq, p, 0);#endif}voidSpanAgent::tx_failure_cb(Packet *p, void *thunk){ SpanAgent *agent = (SpanAgent*) thunk; hdr_cmn *cmnh = (hdr_cmn*)p->access(agent->off_cmn_); cmnh->retries_++; if (cmnh->xmit_reason_ != XMIT_REASON_BUF && cmnh->next_hop_ != (int)MAC_BROADCAST && agent->alive()) {#if 0 fprintf(stderr, "# %d remove %d because tx failed, reason: %d\n", agent->id(), cmnh->next_hop_, cmnh->xmit_reason_);#endif agent->_neighbors.remove_coordinator(agent->id(), cmnh->next_hop_); agent->_neighbors.remove_neighbor(cmnh->next_hop_); Packet *pp = 0; while((pp = agent->_mac->reclaim_packet(cmnh->next_hop_))) { agent->forward_pkt(pp); pp = 0; } int i=0; Packet* vec[64]; // cheat: we know IFQ max len is 50... while((pp = agent->_real_ifq->prq_get_nexthop(cmnh->next_hop_))) { vec[i] = pp; i++; if (i == 64) break; pp = 0; } for (int j=0; j<i; j++) agent->forward_pkt(vec[j]); } // don't retry broadcasts or drop because of stale packets in buffer if (!agent->alive() || cmnh->next_hop_ == (int)MAC_BROADCAST || cmnh->retries_ >= 3 || cmnh->xmit_reason_ == XMIT_REASON_BUF) { if (cmnh->xmit_reason_ == XMIT_REASON_BUF) agent->drop(p, SPAN_DROP_BUF); else agent->drop(p, SPAN_DROP_TX_FAILED); return; } agent->forward_pkt(p);}voidSpanAgent::output_loc(){ if (_my_id == 1) fprintf(stderr,"Locations of alive nodes:\n"); double x, y, z; (God::instance()->nodelist[_my_id])->getLoc(&x, &y, &z); if(active() && _my_id>_srcsink) fprintf(stderr,"%d: %f %f\n",_my_id,x,y); return;}voidSpanAgent::dump_table(){ if (_my_id == 1) fprintf(stderr,"StartOfDump\n"); double x, y, z;#if((PROTOCOL==SPAN_CLEAR) || (PROTOCOL==CLEAR)) NeighborTable::Neighbor *self = _neighbors.search_neighbor(_my_id); (God::instance()->nodelist[_my_id])->getLoc(&x, &y, &z); if(active()){//&& self->is_coordinator){ fprintf(stderr,"%d: %f %f -energy is %f\n",_my_id,x,y,_energy_model->energy()); } return;#endif LLIterator *ni = _neighbors.neighbors(); NeighborTable::Neighbor *n = (NeighborTable::Neighbor*)ni->peek(); (God::instance()->nodelist[_my_id])->getLoc(&x, &y, &z); while (n) { fprintf(stderr, "%f %f %d %c%d %d %d %d %f %f %3f\n", x, y, _my_id, n->is_coordinator ? 'c' : 'n', n->id, n->id, 1, n->nounce, _energy_model->energy(), _energy_model->initialenergy(),sqrt((x-n->x)*(x-n->x)+(y-n->y)*(y-n->y))); n = (NeighborTable::Neighbor*)ni->next(); } delete ni;}static class SpanAgentClass : public TclClass{public: SpanAgentClass() : TclClass("Agent/SpanAgent") { } TclObject* create(int, const char *const *) { return new SpanAgent(); }} class_SpanAgent;SpanAgent::SpanAgent() : Agent(PT_SPAN), _event_handler(this), _announce_coordinator_handler(this),#if((PROTOCOL==SPAN_CLEAR) || (PROTOCOL==CLEAR)) withdraw_coordinator_handler_(this),#endif _usespan(true), _usepsm(true), _srcsink(0){ _pkts_sent = 0; _pkts_received = 0; _pkts_hops = 0;#if((PROTOCOL==SPAN_CLEAR) || (PROTOCOL==CLEAR)) bind("SideLen",&SideLen);#endif bind("off_span_hello_", &_off_span_hello); bind("off_span_", &_off_span); bind("off_ll_", &_off_ll); bind("off_mac_", &_off_mac); bind("off_ip_", &_off_ip); _gfrt = new GFRouter(_neighbors);}intSpanAgent::command(int argc, const char*const* argv){ TclObject *obj; if (argc == 2) { if (strcasecmp(argv[1], "start-span") == 0) { start(); return TCL_OK; } if (strcasecmp(argv[1], "dump-tables") == 0) { dump_table(); return TCL_OK; } if (strcasecmp(argv[1], "output_loc") == 0) { output_loc(); return TCL_OK; } } else if(argc == 3) { if (strcasecmp(argv[1], "ip-addr") == 0) { _my_id = atoi(argv[2]); #if((PROTOCOL==SPAN_CLEAR) || (PROTOCOL==CLEAR)) self_.id = _my_id;#endif return TCL_OK; } else if (strcasecmp(argv[1], "srcsink") == 0) { _srcsink = atoi(argv[2]); return TCL_OK; } else if (strcasecmp(argv[1], "usepsm") == 0) { int usepsm = atoi(argv[2]); if (usepsm > 0) _usepsm = true; else _usepsm = false; return TCL_OK; } else if (strcasecmp(argv[1], "usespan") == 0) { int usespan = atoi(argv[2]); if (usespan > 0) _usespan = true; else _usespan = false; return TCL_OK; } else if (strcasecmp(argv[1], "addnetif") == 0) { _netif = (SharedMedia *) TclObject::lookup(argv[2]);; if (_netif == 0) { fprintf(stderr, "SpanAgent: %s lookup of %s failed\n", argv[1], argv[2]); return TCL_ERROR; } assert(_netif); return TCL_OK; } else if (strcasecmp(argv[1], "mobile-node") == 0) { _mobile_node = (MobileNode *) TclObject::lookup(argv[2]);; if (_mobile_node == 0) { fprintf(stderr, "SpanAgent: %s lookup of %s failed\n", argv[1], argv[2]); return TCL_ERROR; } assert(_mobile_node); return TCL_OK; } } else if (argc == 4) { if (strcasecmp(argv[1], "add-mac") == 0) { _real_ifq = _ifq = (PriQueue *) TclObject::lookup(argv[2]); if (_ifq == 0) { fprintf(stderr, "SpanAgent: %s lookup of %s failed\n", argv[1], argv[2]); return TCL_ERROR; } _mac = (Mac802_11 *) TclObject::lookup(argv[3]); if (_mac == 0) { fprintf(stderr, "SpanAgent: %s lookup of %s failed\n", argv[1], argv[3]); return TCL_ERROR; } return TCL_OK; } if (strcasecmp(argv[1], "add-ll") == 0) { if( (obj = TclObject::lookup(argv[2])) == 0) { fprintf(stderr, "SpanAgent: %s lookup of %s failed\n", argv[1], argv[2]); return TCL_ERROR; } _ll = (NsObject*) obj; if((obj = TclObject::lookup(argv[3])) == 0) { fprintf(stderr, "SpanAgent: %s lookup of %s failed\n", argv[1], argv[3]); return TCL_ERROR; } _ifq = (PriQueue *) obj; return TCL_OK; } } else if (argc == 5) { if (strcasecmp(argv[1], "add-mac") == 0) { _ifq = (PriQueue *) TclObject::lookup(argv[2]); if (_ifq == 0) { fprintf(stderr, "SpanAgent: %s lookup of %s failed\n", argv[1], argv[2]); return TCL_ERROR; } _real_ifq = (PriQueue *) TclObject::lookup(argv[3]); if (_real_ifq == 0) { fprintf(stderr, "SpanAgent: %s lookup of %s failed\n", argv[1], argv[3]); return TCL_ERROR; } _mac = (Mac802_11 *) TclObject::lookup(argv[4]); if (_mac == 0) { fprintf(stderr, "SpanAgent: %s lookup of %s failed\n", argv[1], argv[4]); return TCL_ERROR; } return TCL_OK; } } return Agent::command(argc, argv);} voidSpanAgent::start(){#ifdef ALL_ACTIVE _is_coordinator = true;#else _is_coordinator = false;#endif _announce_pending = false; _withdraw_meter = 0; _last_withdraw = 0; _last_withdraw_seen = 0; _is_tentative = false; _energy_model = _mobile_node->energy_model(); assert(_energy_model); _last_force = 0; _force_counter = 0; NeighborTable::Neighbor *self = new NeighborTable::Neighbor; self->id = _my_id; self->nounce = 0; self->x = 0; self->y = 0; self->is_coordinator = false; self->coordinators = 0; _neighbors.add_neighbor(self); #if((PROTOCOL==SPAN_CLEAR) || (PROTOCOL==CLEAR)) withdraw_pending_ = false; initial_energy_ = _energy_model->energy(); fprintf(stderr, "#Node %d init energy is %f\n",_my_id,initial_energy_);#endif double j = jitter(10); Scheduler::instance().schedule (&_event_handler, &_event_handler_event, j);#ifndef ALL_ACTIVE sleep();#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -