NS2安装LEACH协议
1.解压出来的文件夹有个mit,复制到~/ns2.35/目录下
2.打开每个文件,看看有“#ifdef MIT_uAMPS …… #endif“这样的部分,就贴到ns2.35下的同名文件同样位置中去。
2.1 app.c
Application::Application() : enableRecv_(0), enableResume_(0) { #ifdef MIT_uAMPS enableRecv_ = 1; #endif } #ifdef MIT_uAMPS void Application::recv(int link_dst, int data_size, char* meta_data, int sender) { if (! enableRecv_) return; Tcl& tcl = Tcl::instance(); tcl.evalf("%s recv %d %d %d %s", name_, link_dst, sender, data_size, meta_data); } void Application::recv(char* ch_index) { if (! enableRecv_) return; Tcl& tcl = Tcl::instance(); tcl.evalf("%s recv %s", name_, ch_index); } #endif
2.2 app.h
#ifdef MIT_uAMPS virtual void recv(int sendto, int data_size, char* meta_data, int sender); virtual void recv(char* ch_index); #endif
2.3 mobilenode.cc
#ifdef MIT_uAMPS #if 0 sprintf(log_target->buffer(), "M %.5f %d (%.2f, %.2f, %.2f), (%.2f, %.2f), %.2f", s.clock(), index_, X, Y, Z, destX, destY, speed); log_target->dump(); #endif #endif
2.4 packet.cc
#ifdef MIT_uAMPS int hdr_rca::offset_; // static offset of rca header #endif #ifdef MIT_uAMPS class RCAHeaderClass : public PacketHeaderClass { public: RCAHeaderClass() : PacketHeaderClass("PacketHeader/RCA", sizeof(hdr_rca)) { bind_offset(&hdr_rca::offset_); } } class_rcahdr; #endif
2.5 packet.h
#ifdef MIT_uAMPS #define HDR_RCA(p) ((struct hdr_rca*)(p)->access(hdr_rca::offset_)) #define HDR_MACSensor(p) ((struct hdr_macSensor*)(p)->access(hdr_mac::offset_)) #endif #ifdef MIT_uAMPS static const packet_t PT_RCA = 74 #endif #ifdef MIT_uAMPS name_[PT_RCA] = "rca"; #endif #ifdef MIT_uAMPS static void PrintRcHeader(Packet *p, char *layer); #endif #ifdef MIT_uAMPS struct hdr_rca { int msg_type_; char meta_[1000]; int meta_size_; float dist_to_dest_; int dist_est_; int rca_src_; int rca_mac_dst_; int rca_link_dst_; int code_; static int offset_; // offset for this header inline static int& offset() { return offset_; } inline static hdr_rca* access(Packet* p) { return (hdr_rca*) p->access(offset_); } /* per-field member functions */ inline int& msg_type() { return (msg_type_); } inline int& meta_size() { return (meta_size_); } inline float& get_dist() { return (dist_to_dest_); } inline int& dist_est() { return (dist_est_); } inline void set_meta(const char* data) { meta_size_ = strlen(data); if (meta_size_ > maxmetasize()) { printf("Error: Meta size %d too large (max = %d).\n", meta_size_, maxmetasize()); exit(1); } memcpy(meta_, data, meta_size_+1); } inline char* const meta() { return (meta_); } inline int maxmetasize() { return (sizeof(meta_)); } inline int& rca_src() { return (rca_src_); } inline int& rca_mac_dst() { return (rca_mac_dst_); } inline int& rca_link_dst() { return (rca_link_dst_); } inline int& get_code() { return (code_); } }; #endif #ifdef MIT_uAMPS inline void Packet::PrintRcHeader(Packet *p, char *layer) { hdr_cmn *hdr = HDR_CMN(p); hdr_rca *rca_hdr = HDR_RCA(p); printf("%s Layer received: Type=%d data_size=%d\n\tMeta = %s\n\tSource = %x\n\tTarget = %x\n\tLink_target = %x\n",layer,rca_hdr->msg_type(), hdr->size(), rca_hdr->meta(),rca_hdr->rca_src(), rca_hdr->rca_mac_dst(), rca_hdr->rca_link_dst()); } #endif #ifdef MIT_uAMPS hdr_rca* rca_hdr = HDR_RCA(p); rca_hdr->meta_size_ = 0; #endif #ifdef MIT_uAMPS hdr_rca* ch = HDR_RCA(this); hdr_rca* new_ch = HDR_RCA(p); if (ch->meta_size_) { new_ch->meta_size_ = ch->meta_size_; memcpy(new_ch->meta_, ch->meta_, ch->meta_size_+1); } #endif
2.6 channel.cc
#ifdef MIT_uAMPS /* * When nodes are dead (e.g., they have run out of energy), * they must be removed from the network. */ else if(strcmp(argv[1], "removeif") == 0) { ((Phy*) obj)->deletechnl(&ifhead_); return TCL_OK; } #endif
2.7 ll.h
#ifdef MIT_uAMPS public: #endif #ifdef MIT_uAMPS double mindelay_; #endif
2.8 mac.cc
#ifdef MIT_uAMPS bind("bandwidth_", &bandwidth_); #endif
2.9 phy.cc
#ifdef MIT_uAMPS /* Keep track of when transmission ends for carrier sense. */ /* Since CDMA can be used with CSMA, need to keep track of when transmissions from each CDMA code will end. */ cs_end_ = new double[1000]; for (int i=0; i<1000; i++) cs_end_[i] = 0; #endif
2.10 phy.h
#ifdef MIT_uAMPS inline void deletechnl(struct if_head *head) { LIST_REMOVE(this, chnl_link_); //delete channel_; } #endif #ifdef MIT_uAMPS double *cs_end_; // time when carrier sence will end per code public: inline double csEnd(int code) { return cs_end_[code]; } #endif
2.11 wireless-phy.cc
#ifdef MIT_uAMPS alive_ = 1; // 0 = dead, 1 = alive bandwidth_ = 1000000; // 100 Mbps Efriss_amp_ = 100 * 1e-12; // Friss amp energy (J/bit/m^2) Etwo_ray_amp_ = 0.013 * 1e-12; // Two-ray amp energy (J/bit/m^4) EXcvr_ = 50 * 1e-9; // Xcvr energy (J/bit) // Use this base threshold to get a "hearing radius" of ~ 1 m Pfriss_amp_ = Efriss_amp_ * bandwidth_; // Friss power (W/m^2) Ptwo_ray_amp_ = Etwo_ray_amp_ * bandwidth_; // Two-ray power (W/m^4) PXcvr_ = EXcvr_ * bandwidth_; // Xcvr power (W) sleep_ = 0; // 0 = awake, 1 = asleep ss_ = 1; // amount of spreading time_finish_rcv_ = 0; dist_ = 0; // approx. distance to transmitter energy_ = 0; #else bandwidth_ = 2*1e6; // 2 Mb Pt_ = pow(10, 2.45) * 1e-3; // 24.5 dbm, ~ 281.8mw #endif #ifdef MIT_uAMPS /* * Set CSThresh_ for receiver sensitivity and RXThresh_ for required SNR. */ CSThresh_ = 1e-10; RXThresh_ = 6e-9; #else CSThresh_ = 1.559e-11; RXThresh_ = 3.652e-10; #endif #ifdef MIT_uAMPS bind("alive_",&alive_); bind("bandwidth_",&bandwidth_); bind("Efriss_amp_", &Efriss_amp_); bind("Etwo_ray_amp_", &Etwo_ray_amp_); bind("EXcvr_", &EXcvr_); bind("sleep_",&sleep_); bind("ss_",&ss_); bind("dist_",&dist_); #endif #ifdef MIT_uAMPS else if (strcasecmp(argv[1], "attach-energy") == 0) { energy_ = (EnergyResource*) obj; return TCL_OK; } #endif #ifdef MIT_uAMPS /* * The power for transmission depends on the distance between * the transmitter and the receiver. If this distance is * less than the crossover distance: * (c_d)^2 = 16 * PI^2 * L * hr^2 * ht^2 * --------------------------------- * lambda^2 * the power falls off using the Friss equation. Otherwise, the * power falls off using the two-ray ground reflection model. * Therefore, the power for transmission of a bit is: * Pt = Pfriss_amp_*d^2 if d < c_d * Pt = Ptwo_ray_amp_*d^4 if d >= c_d. * The total power dissipated per bit is PXcvr_ + Pt. */ hdr_cmn *ch = HDR_CMN(p); hdr_rca *rca_hdr = HDR_RCA(p); double d = rca_hdr->get_dist(); double hr, ht; // height of recv and xmit antennas double tX, tY, tZ; // transmitter location node_->getLoc(&tX, &tY, &tZ); ht = tZ + ant_->getZ(); hr = ht; // assume receiving node and antenna at same height double crossover_dist = sqrt((16 * PI * PI * L_ * ht * ht * hr * hr) / (lambda_ * lambda_)); if (d < crossover_dist) if (d > 1) Pt_ = Efriss_amp_ * bandwidth_ * d * d; else // Pfriss_amp_ is the minimum transmit amplifier power. Pt_ = Efriss_amp_ * bandwidth_; else Pt_ = Etwo_ray_amp_ * bandwidth_ * d * d * d * d; PXcvr_ = EXcvr_ * bandwidth_; if (energy_) { if (energy_->remove(pktEnergy(Pt_, PXcvr_, ch->size())) != 0) alive_ = 0; } #endif #ifdef MIT_uAMPS hdr_cmn *ch = HDR_CMN(p); hdr_rca *rca_hdr = HDR_RCA(p); /* * Record when this packet ends and its code. */ int code = rca_hdr->get_code(); cs_end_[code] = Scheduler::instance().clock() + txtime(p); /* * If the node is asleep, drop the packet. */ if (sleep_) { //printf("Sleeping node... carrier sense ends at %f\n", cs_end_); //fflush(stdout); pkt_recvd = 0; goto DONE; } #endif #ifdef MIT_uAMPS /* * Only remove energy from nodes that are awake and not currently * transmitting a packet. */ if (Scheduler::instance().clock() >= time_finish_rcv_) { PXcvr_ = EXcvr_ * bandwidth_; if (energy_) { if (energy_->remove(pktEnergy((double)0, PXcvr_,ch->size())) != 0) alive_ = 0; } time_finish_rcv_ = Scheduler::instance().clock() + txtime(p); } /* * Determine approximate distance of node transmitting node * from received power. */ double hr, ht; // height of recv and xmit antennas double rX, rY, rZ; // receiver location double d1, d2; double crossover_dist, Pt, M; node_->getLoc(&rX, &rY, &rZ); hr = rZ + ant_->getZ(); ht = hr; // assume transmitting node antenna at same height crossover_dist = sqrt((16 * PI * PI * L_ * ht * ht * hr * hr) / (lambda_ * lambda_)); Pt = p->txinfo_.getTxPr(); M = lambda_ / (4 * PI); d1 = sqrt( (Pt * M * M) / (L_ * Pr) ); d2 = sqrt(sqrt( (Pt * hr * hr * ht * ht) / Pr) ); if (d1 < crossover_dist) dist_ = d1; else dist_ = d2; rca_hdr->dist_est() = (int) ceil(dist_); #endif #ifdef MIT_uAMPS double WirelessPhy::pktEnergy(double pt, double pxcvr, int nbytes) { /* * Energy (in Joules) is power (in Watts=Joules/sec) divided by * bandwidth (in bits/sec) multiplied by the number of bytes, times 8 bits. */ // If data has been spread, power per DATA bit should be the same // as if there was no spreading ==> divide transmit power // by spreading factor. double bits = (double) nbytes * 8; pt /= ss_; double j = bits * (pt + pxcvr) / bandwidth_; return(j); } #endif
2.12 wireless-phy.h
#ifdef MIT_uAMPS #include <mit/rca/energy.h> #endif #ifdef MIT_uAMPS EnergyResource *energy_; // Energy resource int alive_; // 0 = dead, 1 = alive //endif //ifdef MIT_uAMPS_temp double Efriss_amp_; // Xmit amp energy (J/bit/m^2) double Etwo_ray_amp_; // Xmit amp energy (J/bit/m^4) double EXcvr_; // Xcvr energy (J/bit) double Pfriss_amp_; // Friss base transmission power (W/m^2) double Ptwo_ray_amp_; // Two-ray base transmission power (W/m^4) double PXcvr_; // Xcvr Power (W) int sleep_; // 0 = awake, 1 = asleep int ss_; // amount of spreading double time_finish_rcv_; double dist_; // approx. distance to transmitter private: double pktEnergy(double pt, double pxcvr, int nbytes); #endif 据说把上面这个的private注释掉。 还有下面,把第二句前面的//去掉 // Why phy has a node_ and this guy has it all over again?? // MobileNode* node_; // Mobile Node to which interface is attached .
2.13 wireless-phy.cc wireless-phyExt.cc
mac/wireless-phy.cc(大约235行),wireless-phyExt.cc (大约132行),将代码中的 node_ = (Node *)obj; 改为 #ifdef MIT_uAMPS node_ = (MobileNode *)obj; #else node_ = (Node *)obj; #endif
2.14 cmu-trace.cc
#ifdef MIT_uAMPS #include <mit/rca/rcagent.h> #endif #ifdef MIT_uAMPS case PT_RCA: format_rca(p,offset); break; #endif #ifdef MIT_uAMPS case PT_RCA: break; #endif #ifdef MIT_uAMPS void CMUTrace::format_rca(Packet *p, int offset) { struct hdr_rca *rca_hdr = HDR_RCA(p); char op = (char) type_; switch (rca_hdr->msg_type()) { case ADV: op = ADV_CHAR; break; case REQ: op = REQ_CHAR; break; case DATA: op = DATA_CHAR; break; default: //printf("format_rca: Warning, unknown meta-data type %d\n",rca_hdr->msg_type()); op = (char) type_; break; } sprintf(pt_->buffer() + offset, "------- [%c %d %d %d] ", op, rca_hdr->rca_src(), rca_hdr->rca_link_dst(), rca_hdr->rca_mac_dst() ); return; } #endif
2.15 cmu-trace.h
#ifdef MIT_uAMPS #define ADV_CHAR 'A' #define REQ_CHAR 'R' #define DATA_CHAR 'D' #endif #ifdef MIT_uAMPS void format_rca(Packet *p, int offset); #endif
3.复制mac-sensor.cc, mac-sensor.h, mac-sensor-timers.cc, mac-sensor-timers.h到对应文件夹中。
4.将ns-allinone-2.34/ns-2.34/tcl/ex目录下的wireless.tcl重命名为 wireless_1.tcl,再将leach/tcl/ex目录下的wireless.tcl复制到ns-allinone-2.34/ns-2.34 /tcl/ex中
5.将leach/tcl/mobility目录下的四个文件复制到ns-allinone-2.34/ns-2.34/tcl/mobility中
6.修改/ns-2.35/mit/uAMPS/ns-leach.tcl,将set dst_ $mac_dsc改为set dsc_addr $mac_dst
7.修改Makefile
在DEFINE行的最后添加-DMIT_uAMPS 在INCLUDE行的中间添加-I./mit/rca -I./mit/uAMPS \
在OBJ_CC 下面代码中gaf/gaf.o \之前添加
mit/rca/energy.o mit/rca/rcagent.o \
mit/rca/rca-ll.o mit/rca/resource.o \
mac/mac-sensor-timers.o mac/mac-sensor.o mit/uAMPS/bsagent.o \
8.将leach目录下的test,leach_test,package_up三个文件复制到ns-allinone-2.35/ ns-2.35中
9.修改test中内容为:
#!/bin/bash export RCA_LIBRARY="/home/zhuangyu/ns-allinone-2.35/ns-2.35/mit/rca" export uAMPS_LIBRARY="/home/zhaungyu/ns-allinone-2.35/ns-2.35/mit/uAMPS" sleep 1 cd tcl/ex ns wireless-demo-csci694.tcl sleep 2 cd ../../ ./leach_test
10.到ns2.35目录下 make clean,然后make。重新编译ns2. 之后./test运行。
11.进入目录dirname="mit/leach_sims",会看到文件filename.err和filename.out,检查是否出错。
来源:https://www.cnblogs.com/wlzy/p/6005456.html