Page MenuHomec4science

neighbors.hh
No OneTemporary

File Metadata

Created
Thu, Jul 10, 04:36

neighbors.hh

#ifndef CLICK_NEIGHBORS_HH
#define CLICK_NEIGHBORS_HH
#include <click/element.hh>
#include <click/notifier.hh>
#include <click/router.hh>
#include <click/confparse.hh>
#include <click/timer.hh>
#include <click/error.hh>
#include <click/etheraddress.hh>
#include <click/hashtable.hh>
#include <click/vector.hh>
#include <click/config.h>
#include <click/args.hh>
#include <click/string.hh>
#include <click/straccum.hh>
#include <clicknet/udp.h>
#include <click/confparse.hh>
//#include <stdio.h>
//#include <stdlib.h>
//#include <ctime>
#include "routinglinks.hh"
//For debug_output:
#ifdef CLICK_USERLEVEL
# include <stdarg.h>
# include <click/fromfile.hh> //fromfile.hh includes stio.h, which only works in userland
#endif
#define TIME_PLC_CAPA 150
CLICK_DECLS
/*
* class Neighbors:
* Click element in charge of periodically broadcasting HELLO messages to neighbors.
* Once a node receives a HELLO message, it should add the corresponding neighbor to its table.
* This table is publicly available.
*/
class RoutingLinks;
class Neighbors : public Element {
public:
Neighbors();
~Neighbors();
//This is to return _notifier
void *cast(const char *);
const char *class_name() const { return "Neighbors"; }
const char *port_count() const { return "2-4/2-5"; }
//When both ETH_ADDR_1 and ETH_ADDR_2 are given:
//push input 0 : HELLO msgs from plc interface
//push input 1 : HELLO msgs from wifi interface
//push input 2 : frames from wifi monitor interface (moni0)
//push input 3 : MMTYPE msgs from PLC interface (need promisc mode (?) )
//
//push output 0 : HELLO msgs to plc interface
//push output 1 : HELLO msgs to wifi interface
//push output 2 : empty wifi frames to measure PHY rate
//push output 3 : tone map requests to PLC interface + empty unicast PLC frames
//push output 4 : fwd PLC packets parsed for reply
//When only ETH_ADDR_1 is given (wifi):
//push input 0 : HELLO msgs from wifi interface
//push input 1 : frames from wifi monitor (moni0)
//
//push output 0 : HELLO msgs to wifi interface
//push output 1 : empty wifi frames
//When only ETH_ADDR_2 is given (plc):
//push input 0 : HELLO msgs from plc interface
//push input 1 : MMTYPE msgs from PLC interfac
//
//push output 0 : HELLO msgs to plc interface
//push output 1 : tone map requests to PLC interface + empty unicast PLC frames
//push output 2 : fwd PLC packets
const char *processing() const { return "h/h"; }
int configure(Vector<String> &, ErrorHandler *);
int initialize(ErrorHandler *);
void push(int, Packet*);
/*
* Useful methods to get next hops along a Route, and build MAC headers
* (used mainly from Forwarder)
*/
EtherAddress get_eth_addr_from_last_bytes(unsigned char *data);
int get_interface_to_neighbor(EtherAddress neighbor);
/*
* These are the methods interesting to the outside world
*/
LinksTable get_outgoing_links(){
//returns a list of current neighbors
LinksTable copy;
copy = _neighbors;
return copy;
}
uint32_t get_capa_for_neighbor(EtherAddress addr){
NeighborLink *link = _neighbors.get_pointer(addr);
if(link != 0){
return link->capa;
} else {
return 0;
}
}
bool neighbor_exists(EtherAddress addr){
return (_neighbors.get_pointer(addr) != 0);
}
void registerListener(NeighborsListener *l){
//call this method to register yourself
_listeners.push_back(l);
}
uint32_t get_timeout() {return _timeout_duration;}
String print_info();
void set_debug(bool debug) {_debug=debug;if(!_debug)_verb_debug=false;}
void set_verb_debug(bool debug) {_verb_debug=debug;if(_verb_debug)_debug=true;}
void set_active(bool active) {_active=active;}
void set_send_empty_frames(bool b) {if(b&&!_send_empty_frames) _frame_timer.schedule_now(); _send_empty_frames=b;}
void set_load(uint32_t load) {_load_estimation=load;}
void set_print_updates(bool debug) {_print_updates=debug;}
static int debug_handler(const String &, Element *, void *,ErrorHandler *);
static int active_handler(const String &, Element *, void *,ErrorHandler *);
static int load_handler(const String &, Element *, void *,ErrorHandler *);
static int reset_handler(const String &, Element *, void *,ErrorHandler *);
static int print_updates_handler(const String &, Element *, void *,ErrorHandler *);
void add_handlers();
void reinitialize_counters() { _nb_retry.clear();_nb_packets.clear();}
void set_rl_elmt(RoutingLinks *rl) {_rl_elmt = rl;}
bool get_is_reliable() {return _is_reliable_int1 && _is_reliable_int2;}
IPAddress my_ip();
IPAddress get_ip(unsigned char *);
IPAddress get_ip(EtherAddress);
private:
RoutingLinks *_rl_elmt;
ActiveNotifier _notifier;
bool _static; //whether to read neighbors from a file or not
#ifdef CLICK_USERLEVEL
FromFile _ff;
#endif
bool _debug;
bool _verb_debug;
bool _active;
uint8_t _nr_interfaces;
bool _eth_addr1_present;
bool _eth_addr2_present;
bool _addr2_is_plc;
EtherAddress _eth_addr1, _eth_addr2, _empty_eth; //the first two are wifi and plc, respectively.
EtherAddress _plc_chip_addr;
uint32_t _period_hello; // period for sending hello packets in s
uint32_t _period_frame_ms; //period for sending frames for capcity estimation in ms.
uint32_t _period_capacity_estimation;
uint32_t _timeout_duration; //in s.
uint32_t _current_int2_index; //index in the HT of the PLC node for which we made the last tone map request
EtherAddress _current_plc_addr; //Addr of the PLC node for which we made the last tone map request
uint32_t _current_int1_index; //index in the HT of the Wifi node for which we sent the last frame
uint32_t _current_int1_index_estimation; //index in the HT of the Wifi node for which we sent the last frame
uint32_t _number_estimations;
uint32_t _load_estimation;
uint32_t _size_estimation_packet;
int _print_stat_freq;
Timestamp _last_time_print;
Timestamp _now;
Timestamp _begin;
bool _csv_print;
bool _print_updates;
bool _hello_ip;
bool _pass_int2;
bool _pass_int1;
bool _send_empty_frames;
bool _estimated_plc_end_chunk;
bool _all_neighbors_plc;
bool _is_reliable_int1;
bool _is_reliable_int2;
// PLC interface cannot estimate more than 7 neighbors at a time: divide in chunks of less than 7 neighbors
int _plc_estimation_chunk_index; // index of PLC neighbor chunk for which we estimate capacity
Vector<EtherAddress> _vector_current_plc_neighbors;
Timestamp _last_chunk_change; // time at which we changed chunk for the last time
int _nb_plc_neighbors;
Vector<Vector<EtherAddress> > _group_plc_neighbors; // group of PLC neighbors (defined statically)
int _group_index;
bool _capacity_tonemap_moni;
HashTable<EtherAddress, Vector<int> > _last_packets;
HashTable<EtherAddress, uint32_t> _total_packets;
HashTable<EtherAddress, Vector<int> > _retries_packets;
HashTable<EtherAddress, Vector<uint32_t> > _current_mcs_array;
HashTable<EtherAddress, uint32_t> _nb_retry;
HashTable<EtherAddress, uint32_t> _nb_packets;
HashTable<EtherAddress, uint32_t> _nb_packets_rate;
uint32_t _last_seq_number;
//List of neighbors
LinksTable _neighbors;
//Mapping from last bytes to full eth addresses (for fast forwarding)
HashTable<LastAddrBytes, EtherAddress> _lastbytes2neighbor;
int parse_file(ErrorHandler *);
void parse_hello(Packet* p, int port);
void parse_wifi_frame(const Packet *p);
Timer _hello_timer;
Timer _frame_timer;
Timer _capacity_estimation_timer;
void run_timer(Timer *timer);
void request_tone_maps(EtherAddress dst);
uint32_t processToneMapRep(click_hp_av_tone_map_rep *tm_rep);
uint8_t get_carrier_modulation(short unsigned int modulation, struct modulation_stats *stats);
//list & notify listeners:
Vector<NeighborsListener *> _listeners;
void notifyListeners(){
for(int i=0;i<_listeners.size();i++) {
_listeners[i]->neighborsChanged();
}
// for(Vector<NeighborsListener *>::iterator it = _listeners.begin(); it; ++it){
// click_chatter("Notifying listener %d", i);
// (*it)->neighborsChanged();
// i++;
// }
}
void send_mm_plc();
void rec_mm_plc(Packet *);
void capacity_estimation_wifi();
//uint32_t capacity_estimation_wifi(EtherAddress);
Vector<uint32_t> _mcs_to_rate_20_LG;
Vector<uint32_t> _mcs_to_rate_20_SG;
Vector<uint32_t> _mcs_to_rate_40_LG;
Vector<uint32_t> _mcs_to_rate_40_SG;
HashTable<EtherAddress, EtherAddress> _plc_mac;
void set_plc_neighbor_groups() {
Vector<EtherAddress> vector1;
EtherAddress eth;
cp_ethernet_address("00:0D:B9:3D:C3:EA",&eth);
vector1.push_back(eth);
cp_ethernet_address("00:0D:B9:3D:C2:AA",&eth);
vector1.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:9A:9A",&eth);
vector1.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A0:6E",&eth);
vector1.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A0:06",&eth);
vector1.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A0:92",&eth);
vector1.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:9E:FE",&eth);
vector1.push_back(eth);
if(is_in_vector(vector1, _eth_addr2))
_group_index = 1;
Vector<EtherAddress> vector2 ;
cp_ethernet_address("00:0D:B9:3E:9E:9E",&eth);
vector2.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A0:9E",&eth);
vector2.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A1:16",&eth);
vector2.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A2:F6",&eth);
vector2.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:9B:7E",&eth);
vector2.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A0:7E",&eth);
vector2.push_back(eth);
if(is_in_vector(vector2, _eth_addr2))
_group_index = 2;
Vector<EtherAddress> vector3 ;
cp_ethernet_address("00:0D:B9:3E:99:9E",&eth);
vector3.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A1:92",&eth);
vector3.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A0:FA",&eth);
vector3.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A0:BE",&eth);
vector3.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:99:7A",&eth);
vector3.push_back(eth);
if(is_in_vector(vector3, _eth_addr2))
_group_index = 3;
Vector<EtherAddress> vector4 ;
cp_ethernet_address("00:0D:B9:3E:98:0A",&eth);
vector4.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:97:BA",&eth);
vector4.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:A1:06",&eth);
vector4.push_back(eth);
cp_ethernet_address("00:0D:B9:3E:99:12",&eth);
vector4.push_back(eth);
if(is_in_vector(vector4, _eth_addr2))
_group_index = 4;
_group_plc_neighbors.push_back(vector1);
_group_plc_neighbors.push_back(vector2);
_group_plc_neighbors.push_back(vector3);
_group_plc_neighbors.push_back(vector4);
click_chatter("[Neighbors] Configured the following groups (I'm member of group %d):", _group_index);
for(int i=0;i<_group_plc_neighbors.size();i++) {
click_chatter(" %s", print_vector(_group_plc_neighbors[i]).c_str());
}
};
#define NR_MCS 16 //Number of MCS rates
void set_mcs_to_rate(){
_mcs_to_rate_20_LG = Vector<uint32_t>(NR_MCS,0);
_mcs_to_rate_20_SG = Vector<uint32_t>(NR_MCS,0);
_mcs_to_rate_40_LG = Vector<uint32_t>(NR_MCS,0);
_mcs_to_rate_40_SG = Vector<uint32_t>(NR_MCS,0);
//20 MHz, Long GI
_mcs_to_rate_20_LG[0] = 6656;
_mcs_to_rate_20_LG[1] = 13312;
_mcs_to_rate_20_LG[2] = 19968;
_mcs_to_rate_20_LG[3] = 26624;
_mcs_to_rate_20_LG[4] = 39936;
_mcs_to_rate_20_LG[5] = 53248;
_mcs_to_rate_20_LG[6] = 59904;
_mcs_to_rate_20_LG[7] = 66560;
_mcs_to_rate_20_LG[8] = 13312;
_mcs_to_rate_20_LG[9] = 26624;
_mcs_to_rate_20_LG[10] = 39936;
_mcs_to_rate_20_LG[11] = 53248;
_mcs_to_rate_20_LG[12] = 79872;
_mcs_to_rate_20_LG[13] = 106496;
_mcs_to_rate_20_LG[14] = 119808;
_mcs_to_rate_20_LG[15] = 133120;
//20 MHz, Short GI
_mcs_to_rate_20_SG[0] = 7373;
_mcs_to_rate_20_SG[1] = 14746;
_mcs_to_rate_20_SG[2] = 22221;
_mcs_to_rate_20_SG[3] = 29594;
_mcs_to_rate_20_SG[4] = 44339;
_mcs_to_rate_20_SG[5] = 59187;
_mcs_to_rate_20_SG[6] = 66560;
_mcs_to_rate_20_SG[7] = 73933;
_mcs_to_rate_20_SG[8] = 14746;
_mcs_to_rate_20_SG[9] = 29594;
_mcs_to_rate_20_SG[10] = 44339;
_mcs_to_rate_20_SG[11] = 59187;
_mcs_to_rate_20_SG[12] = 88781;
_mcs_to_rate_20_SG[13] = 118374;
_mcs_to_rate_20_SG[14] = 133120;
_mcs_to_rate_20_SG[15] = 147866;
//40 MHz, Long GI
_mcs_to_rate_40_LG[0] = 13824;
_mcs_to_rate_40_LG[1] = 27648;
_mcs_to_rate_40_LG[2] = 41472;
_mcs_to_rate_40_LG[3] = 55296;
_mcs_to_rate_40_LG[4] = 82944;
_mcs_to_rate_40_LG[5] = 110592;
_mcs_to_rate_40_LG[6] = 124416;
_mcs_to_rate_40_LG[7] = 138240;
_mcs_to_rate_40_LG[8] = 27648;
_mcs_to_rate_40_LG[9] = 55296;
_mcs_to_rate_40_LG[10] = 82944;
_mcs_to_rate_40_LG[11] = 110592;
_mcs_to_rate_40_LG[12] = 165888;
_mcs_to_rate_40_LG[13] = 221184;
_mcs_to_rate_40_LG[14] = 248832;
_mcs_to_rate_40_LG[15] = 276480;
//40 MHz, Short GI
_mcs_to_rate_40_SG[0] = 15360;
_mcs_to_rate_40_SG[1] = 30720;
_mcs_to_rate_40_SG[2] = 46080;
_mcs_to_rate_40_SG[3] = 61440;
_mcs_to_rate_40_SG[4] = 92160;
_mcs_to_rate_40_SG[5] = 122880;
_mcs_to_rate_40_SG[6] = 138240;
_mcs_to_rate_40_SG[7] = 153600;
_mcs_to_rate_40_SG[8] = 30720;
_mcs_to_rate_40_SG[9] = 61440;
_mcs_to_rate_40_SG[10] = 92160;
_mcs_to_rate_40_SG[11] = 122880;
_mcs_to_rate_40_SG[12] = 184320;
_mcs_to_rate_40_SG[13] = 245760;
_mcs_to_rate_40_SG[14] = 276480;
_mcs_to_rate_40_SG[15] = 307200;
};
// TODO: do matching automatically
void set_plc_mac(){
unsigned char mac_chip[6] = {0x00, 0x50, 0xC2, 0xA2, 0x70, 0x50};
unsigned char mac_eth[6] = {0x00, 0x50, 0xC2, 0xA2, 0x70, 0xB3};
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x1B;
mac_eth[5] =0x7C;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x25;
mac_eth[5] =0x85;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x0A;
mac_eth[5] =0x6E;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x24;
mac_eth[5] =0x84;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x10;
mac_eth[5] =0x72;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x4C;
mac_eth[5] =0x7B;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x23;
mac_eth[5] =0x83;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x1A;
mac_eth[5] =0x82;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x28;
mac_eth[5] =0x88;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x00;
mac_eth[5] =0x64;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x22;
mac_eth[5] =0x81;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x26;
mac_eth[5] =0x86;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x16;
mac_eth[5] =0x78;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x15;
mac_eth[5] =0x77;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x1C;
mac_eth[5] =0x7D;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x0C;
mac_eth[5] =0x70;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
mac_chip[5] = 0x1D;
mac_eth[5] =0x7E;
_plc_mac.set(EtherAddress(mac_chip),EtherAddress(mac_eth));
EtherAddress eth_mac_chip;
EtherAddress eth_mac_eth;
if(!cp_ethernet_address(String("00:0B:3B:79:2D:E0"), &eth_mac_chip) ||
!cp_ethernet_address(String("00:0D:B9:3D:C3:EA"), &eth_mac_eth))
click_chatter("[Neighbors] Error while setting MAC address");
else
_plc_mac.set(eth_mac_chip, eth_mac_eth);
if(!cp_ethernet_address(String("00:0B:3B:79:2D:53"), &eth_mac_chip) ||
!cp_ethernet_address(String("00:0D:B9:3D:C2:AA"), &eth_mac_eth))
click_chatter("[Neighbors] Error while setting MAC address");
else
_plc_mac.set(eth_mac_chip, eth_mac_eth);
};
};
CLICK_ENDDECLS
#endif

Event Timeline