Page MenuHomec4science

acker.cc
No OneTemporary

File Metadata

Created
Mon, Jul 7, 06:28

acker.cc

#include <click/config.h>
#include "acker.hh"
CLICK_DECLS
Acker::Acker()
//: _notifier(ActiveNotifier::SEARCH_CONTINUE_WAKE)
{}
Acker::~Acker(){}
/*
void * Acker::cast(const char *n)
{
if (strcmp(n, ActiveNotifier::EMPTY_NOTIFIER) == 0){
return &_notifier;
}
else
return Element::cast(n);
}
*/
int Acker::configure(Vector<String> &conf, ErrorHandler *errh){
click_chatter("[Acker] enters configure.\n");
//_notifier.initialize(ActiveNotifier::EMPTY_NOTIFIER, router());
_debug = false;
int node_index = -1;
_ack_period_ms = 100;
_time=Timestamp(0);
if (Args(conf, this, errh)
.read("DEBUG", _debug)
.read_m("ROUTING", _routingPaths_name)
.read("ACK_PERIOD", _ack_period_ms)
.read("NODE_INDEX", node_index)
.complete() < 0)
return -1;
if(node_index != -1){
//we are part of a compound element, we need to adapt the names of the elements...
String index_str = String(node_index);
String tempstr = String("node")+index_str.c_str();
tempstr = tempstr + "/";
_routingPaths_name = tempstr + _routingPaths_name.c_str();
}
if(_debug)
click_chatter("[Acker] configure done.\n");
return 0;
}
int Acker::initialize(ErrorHandler *errh){
if(_debug)
click_chatter("[Acker] Initializing...\n");
//errorhandler
Element::initialize(errh);
//routingPaths
_routingPaths_element = (RoutingPaths*)router()->find(_routingPaths_name, errh);
if(!_routingPaths_element){
if(_debug)
click_chatter("[Acker] Error: invalid parameter name for Element RoutingPaths.\n");
return -1;
}
return 0;
}
/**
*
*
*/
void Acker::push(int port, Packet* p){
//Receives a layer 2.5 frame.
//From input 0 : regular traffic
//TODO print messages
assert(port == 0);
//retrieve header
empower_header* rcvd_hdr = (empower_header*)p->data();
if (rcvd_hdr->_type != TRAFFIC_FORCED) {
//send packet
Packet *p_copy_out = p->clone()->uniqueify();
output(0).push(p_copy_out);
}
_time.assign_now();
if(!is_in_hash_table(_lastTimestamp, rcvd_hdr->_route))
_lastTimestamp.set(rcvd_hdr->_route,_time);
//BUILD ACK
if((_time-_lastTimestamp[rcvd_hdr->_route]).msecval() >= _ack_period_ms){
/*String src = String::make_garbage(4);
if (char *x = src.mutable_c_str())
sprintf(x, "%02X%02X",rcvd_hdr->_src[0], rcvd_hdr->_src[1]);
if(_debug)
click_chatter("[Acker] Getting route for (last bytes) %s", src.c_str());*/
//get best route to src from routing element
//Route route = _routingPaths_element->get_best_path_ack(rcvd_hdr->_route._src);
Route route_init = _routingPaths_element->get_route_from_froute(rcvd_hdr->_route);
Route route = route_init.reverse_route();
if (!route.links.empty()) {
FormatedRoute dst = FormatedRoute(route);
Packet* out = Packet::make(sizeof(empower_header)+sizeof(empower_ack));
if (out==NULL){
click_chatter("[Acker] Error : unable to build ACK for packet");
return;
}
//1.build header
empower_header* out_h = (empower_header*)out->data();
out_h->_type = ACK_RTE_PRICES;
out_h->_route = dst;
//Julien: we don't need to set the _src in ACKs
//memcpy(&(out_h->_src), &(rcvd_hdr->_route._dst), NB_BYTES_HOP);
out_h->_seq = rcvd_hdr->_seq;
out_h->_hop = 0;
//2. build payload
empower_ack* out_payload = (empower_ack*)(out->data()+sizeof(empower_header));
memcpy(&(out_payload->_target_route), &(rcvd_hdr->_route), sizeof(FormatedRoute));
if(_debug) {
_time.assign_now();
#ifdef CLICK_USERLEVEL
click_chatter("[Acker %s] Received route price on route %s (to send back in ACK) : %f", _time.unparse().c_str(),
rcvd_hdr->_route.unparse().c_str(), rcvd_hdr->_route_price);
#else
click_chatter("[Acker %s] Received route price on route %s (to send back in ACK) : %d", _time.unparse().c_str(),
rcvd_hdr->_route.unparse().c_str(), rcvd_hdr->_route_price);
#endif
}
out_payload->_route_price = rcvd_hdr->_route_price;
out_payload->_stop_flow = false;
if(_debug)
click_chatter("[Acker %s] Sending ack packet on route %s..\n", _time.unparse().c_str(), dst.unparse().c_str());
output(1).push(out);
_lastTimestamp[rcvd_hdr->_route] = _time;
}
else
click_chatter("[Acker] WARNING: empty route to %s", LastAddrBytes(rcvd_hdr->_route._src).unparse().c_str());
}
p->kill();
}
int
Acker::debug_handler(const String &s, Element *e, void *,
ErrorHandler *errh) {
Acker *elmt = (Acker *)e;
int debug;
if(!cp_integer(s, &debug))
return errh->error("Debug must be 0 or 1");
if (!(debug == 0 || debug == 1))
return errh->error("Debug must be 0 or 1");
elmt->set_debug(debug==1);
return 0;
}
void Acker::add_handlers() {
add_write_handler("debug", debug_handler, 0);
}
CLICK_ENDDECLS
EXPORT_ELEMENT(Acker)
ELEMENT_PROVIDES(Acker)

Event Timeline