📄 ackreceiver.cc
字号:
#include <click/config.h>#include <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>#include <clicknet/ether.h>#include <click/etheraddress.hh>#include <click/ipaddress.hh>#include "ackheader.hh"#include "sendmanager.hh"#include "ackreceiver.hh"AckReceiver::AckReceiver() : Element(1, 0), _aliases(0), _sendmgr(0), _myalias(0) //, _scrambleq(0){}AckReceiver::~AckReceiver(){}intAckReceiver::configure(Vector<String> &conf, ErrorHandler *errh){ int res = cp_va_parse(conf, this, errh, cpKeywords, "ETH", cpEtherAddress, "Ethernet address", &_myea, "ALIASTABLE", cpElement, "Alias table", &_aliases, "SENDMGR", cpElement, "Send Manager", &_sendmgr, //"SCRAMBLEQUEUE", cpElement, "ScrambleQueue element", &_scrambleq, cpEnd); if (!_myea) { return errh->error("ETH not specified"); } if (!_aliases) { return errh->error("ALIASTABLE not specified"); } if (_aliases->cast("AliasTable") == 0) { return errh->error("ALIASTABLE element is not an AliasTable"); } if (!_sendmgr) { return errh->error("SENDMGR not specified"); } if (_sendmgr->cast("SendManager") == 0) { return errh->error("SENDMGR element is not a SendManager"); } /* if (!_scrambleq) { return errh->error("SCRAMBLEQUEUE not specified"); } if (_scrambleq->cast("ScrambleQueue") == 0) { return errh->error("SCRAMBLEQUEUE element is not a ScrambleQueue"); } */ _myalias = _aliases->lookup(_myea); click_chatter("%s: my alias is %u", id().cc(), _myalias); return res;}voidAckReceiver::push(int, Packet *p){ click_ether *eth = (click_ether *)p->data(); click_enc_ack *ackh = (struct click_enc_ack *)(eth+1); click_chatter("%s: push() called", id().cc()); int idx = -1; for (uint16_t i = 0; i < ackh->nentries(); i++) { click_chatter("%s: push() looking for alias index %u", id().cc(), i); if (ackh->get_entry_nb(i) == _myalias) { idx = i; click_chatter("%s: push() matched entry %d of %d", id().cc(), idx, ackh->nentries()); break; } } if (idx >= 0) { EtherAddress nbr = EtherAddress(eth->ether_shost); uint16_t seq = ackh->get_entry_seq(idx); uint8_t bmap = ackh->get_entry_bmap(idx); StringAccum sa; sa << "push() matched ack for nbr " << nbr << ", seq " << seq; click_chatter("%s: %s, bmap %x at %u", id().cc(), sa.c_str(), (uint32_t)bmap, Timestamp::now().msec1()); register_acks(nbr, seq, bmap); } p->kill(); // _scrambleq->register_next_rexmit_wakeup(_sendmgr->get_next_rexmit_time());}voidAckReceiver::register_acks(const EtherAddress &ea, uint16_t seq, uint8_t bmap){ PacketID pid(ea, seq); _sendmgr->register_ack(pid); click_chatter("%s: register_acks called for packet with seq %d at %u", id().cc(), pid._seq, Timestamp::now().msec1()); for (uint32_t i = 1; i <=8; i++) { if (bmap & (0x01 << (i-1))) { pid._seq = ((uint32_t)seq + i) % (1 << 15); click_chatter("%s: register_acks called for packet with seq %d at %u", id().cc(), pid._seq, Timestamp::now().msec1()); _sendmgr->register_ack(pid); } }} EXPORT_ELEMENT(AckReceiver)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -