重复的写一下ns 2.35 移植 leach
上次移植貌似之前改了什么参数,导致distCST_总是50.5,改不回来了。所以决定重新搞起。
其实协议代码就这一份,移来移去的真没意思,需要写新的协议还是不会。。。谁有其他的协议代码,求共享。。。reaver13@126.com。
谁会自己添加新的协议,也求分享教程。。
1 下载leach协议包。
包含Makefile, mit.tar.gz就够了。
2 解压mit.tar.gz到leach文件夹(这名字自拟)
3 解压出来的文件夹有个mit,复制到~/ns2.35/目录下(不知道前面~用的对不对,错了求更改)
先说一下,关于#def MIT_uAMPS 是添加在Makefile中定义的,如果去掉重新编译ns,leach这些修改的部分就不会生效了。
4 一下都是一个一个文件打开,看看有“#ifdef MIT_uAMPS …… #endif“这样的部分,就贴到ns2.35下的同名文件同样位置中去。
(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)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
(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
(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
(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
PT_RCA,
#endif
这一段,在2.35中已不是如此定义,改成:
#ifdef MIT_uAMPS
static const packet_t PT_RCA = 74
#endif
贴过去。74是我的情况,原来PT_NTYPE = 74,加入这个之后,RCA = 74 ,NTYPE改成75。因为NTYPE必须是最后一个。
#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
(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
(7)ll.h
#ifdef MIT_uAMPS
public:
#endif
#ifdef MIT_uAMPS
double mindelay_;
#endif
(8)mac.cc
#ifdef MIT_uAMPS
bind("bandwidth_", &bandwidth_);
#endif
(9)mac-sensor.cc, mac-sensor.h, mac-sensor-timers.cc, mac-sensor-timers.h直接复制过去。
(10)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
(11)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
(12)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
(13)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 .
(14)
<3> mac/wireless-phy.cc(大约235行),wireless-phyExt.cc (大约132行),将代码中的
node_ = (Node *)obj;
改为
#ifdef MIT_uAMPS
node_ = (MobileNode *)obj;
#else
node_ = (Node *)obj;
#endif
(15)将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中
(16)将leach/tcl/mobility目录下的四个文件复制到ns-allinone-2.34/ns-2.34/tcl/mobility中
记得看看~
(17)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
(18) 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
(19)将leach目录下的test,leach_test,package_up三个文件复制到ns-allinone-2.34/ ns-2.34中
(20)
修改/ns-2.35/mit/uAMPS/ns-leach.tcl
将set dst_ $mac_dsc改为set dst_addr $mac_dst
(21)修改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 \
(22)修改test中内容为:
#!/bin/bash
cd tcl/ex
ns wireless-demo-csci694.tcl
sleep 2
cd http://www.cnblogs.com/
./leach_test
(23)到ns2.35目录下 make clean,然后make。重新编译ns2.
(24)之后./test就可以了。
还有问题的可以留言,一起研究。。
但是distCST_成了89.8,是wireless-phy.cc中修改的缘故么?
速度研究出来。。。有懂得请留言回复,或邮箱我,万分感谢。。。