这段时间准备采用跨层设计技术做无线视频传输QoS,于是,先整理了一下网上比较好的一些NS2跨层设计的方法,供大家参考,以节约大家的宝贵时间。
1.
http://hi.baidu.com/vvfang/blog/item/a2c73538722d1c27b8998f95.htmlNS2:跨层设计简单体会2007-12-15 15:15
最近在忙手头上的一篇paper,用到了一些跨层设计的思想,这个思想在无线网络里应用很多了,
比如说地理位置辅助的路由,路由信息辅助的MAC,MAC信息辅助的路由,队列拥塞引发的多路径分流传输等等。不过,在NS2验证的时候实在是不好做。
问题的解决是要吃透Mobile Networking in ns中的第一个示意图,其中的xxtarget_正是可以帮助我们解决问题的东东,方法也很简单:对target指针
进行强制类型转换。当然,也有其它的办法,比如在hdr_cmn头部加一个域,包上上下下的时候把数值代入进去,这样也行,不过要执行一些操作就比较麻烦了。
另外,还有要注意的就是,可能还需要设计一些public函数来操作所需对象的私有变量。由于面向对象机制的原因,很多变量的私有导致不是很好在其它类中操作它们。
看周围的同志们主要做工作的地方有几个:传输层的Agent(新手不要说是App,看看代码先);RTagent,就是被大家做烂了的路由协议;MAC,次做烂的MAC协议;IFq,
拥塞。无线网络里,只看其中一个ms不是很好使,跨层设计和优化的方法可能是必须的。
关于跨层调用读取问题
对于跨层设计我整理了一下我的文档,发上来供大家参考一下,希望那个能够有些帮助!
这个文档很久以前写的,如果那里有错误请通知我,我会及时修改,免得误导他人:)
NS2 跨层调用问题简析
NS2 各层对应的都是一些类,只要得到其他层类的入口指针即可,比如说通过TCL解释器可以得到,也可以自己设置新的包头位置,然其他层的函数直接填写,
但是注意逻辑的正确性。
通过tcl解释器访问从MAC层访问路由层( 我没有未测试过)
Tcl& tcl=Tcl::instance();
int i=mac->index_;
sprintf(tcl.buffer(),"$node_(%d) set ragent_",i);
tcl.eval();
agent=(AODV*)TclObject::lookup(tcl.result());
agent->hello();
从路由层访问所在节点的MAC/IFQ
最简单的方法是通过tcl解释器
IFQ: int i= index;
Queue *ifq;
Tcl& tcl=Tcl::instance();
int i=index;
sprintf(tcl.buffer(),"$node_(%d) set ifq_(0)",i);
tcl.eval();
ifq=(Queue*)TclObject::lookup(tcl.result());
MAC: int i= index;
MAC * mac;
Tcl& tcl=Tcl::instance();
int i=index;
sprintf(tcl.buffer(),"$node_(%d) set mac_(0)",i);
tcl.eval();
mac=(Queue*)TclObject::lookup(tcl.result());
其他方法
至于通过ns手册上面说明的关系来访问,经常出现问题,很多指针没有初始化,要自己写代码才可以使用
类似:
//LL * ll;
//ll=(LL*)mac->link();
//Queue *ifq;
//ifq=(Queue *)ll->downtarget();
3.
http://yueyelmm.blog.163.com/blog/static/2981247320091131144420/NS2跨层设计总结
ns2 2009-02-13 13:14:04 阅读214 评论3 字号:大中小
在网上查询ns2跨层设计后,发现最有用的莫过于SEASON29问里的第28答了,里面介绍了路由层如何访问MAC层信息(见附录),
在 tcl 脚本中初始化:
set rt($i) [$node_($i) agent 255] # 获得路由层协议
$rt($i) set-mac [$node_($i) set mac_(0)] #初始化 mac 对象
其中255是端口号,agent 255代表是路由代理,不适合DSR协议;而mac_(0)中的0是单信道的意思。
对于其他层之间信息的访问(例如,MAC访问队列,MAC访问路由,TCP访问MAC,TCP访问队列等等),道理都是类似的,只要讲相应的名称调换,即可。
aodv、 tora ---> agent 255
dsr ---> dsr_agent_($t)
ll --->ll_($t)
interface --->netif_($t)
mac ---> mac_($t)
arp ---> arptable_($t)
其中,$t应该是用在多信道情况时,一般情况默认为0(单信道)。
例如:从MAC层访问队列的信息
set mymac($i) [$node_($i) set mac_(0)]
$mymac set-que [$node_($i) set ifq_(0)]
其他的同理即可。
注意:TCP进行跨层时,tcl中的定义必需放在tcp绑定节点之后。
eg:set tcp [new Agent/TCP]
$ns_ attach-agent $node_(0) $tcp
$tcp set-route [$node_(0) set dsragent_(0)] //tcp访问dsr层信息;
$tcp set-route [$node_(0) set agent 255] //tcp访问路由层(except dsr)信息;
$tcp set-mac [$node_(0) set mac_(0)] //tcp访问mac层信息;
$tcp set-ifq [$node_(0) set ifq_(0)] //tcp访问队列信息;
附录:(season29问第28答)
怎样在任意层访问下层的信息(包括 netif,mac,ifq,ll 等)
以 aodv 中访问 mac 为例,
(1)在 aodv.h 中增加头文件
#include "mac/mac-802_11.h"
在 AODV 类里面声明
Mac802_11 * mymac;
(2)修改 command()函数,增加以下代码
int
AODV::command(int argc, const char*const* argv) {
。。。
。。。
else if(argc == 3) {
if(strcmp(argv[1], "index") == 0) {
index = atoi(argv[2]);
return TCL_OK;
}//add by season
else if (strcmp(argv[1], "set-mac") == 0)
{
mymac = (Mac802_11 *) TclObject::lookup(argv[2]);
if (mymac == 0)
{
fprintf(stderr, "MESPAgent: %s lookup %s failed.\n", argv[1], argv[2]);
return TCL_ERROR;
}
else
{
//test
printf("Get Node mac bss_id:%d \n", mymac->bss_id());
// fprintf(stderr, "Get Node address .\n", nodeID);
return TCL_OK;
}
}
。。。
。。。
}
(3)在 tcl 脚本中初始化
set rt($i) [$node_($i) agent 255] # 获得路由层协议
$rt($i) set-mac [$node_($i) set mac_(0)] #初始化 mac 对象
(4)然后就可以在 AODV 中通过 mymac 对象访问 mac 的信息
set opt(engmodel) EnergyModel ;#能量模型
set opt(initeng) 10000.0 ;#总能量
set opt(txPower) 0.660 ;#传输能量
set opt(rxPower) 0.395 ;#接受能量
set opt(idlePower) 0.035 ;#待机能量
配置node-config
$ns_ node-config -adhocRouting $val(rp) \
-llType $val(ll) \
-macType $val(mac) \
-ifqType $val(ifq) \
-ifqLen $val(ifqlen) \
-antType $val(ant) \
-propType $val(prop) \
-phyType $val(netif) \
-energyModel $opt(engmodel) \
-initialEnergy $opt(initeng) \
-txPower $opt(txPower) \
-rxPower $opt(rxPower) \
-idlePower $opt(idlePower) \
-topoInstance $topo \
-agentTrace OFF \
-routerTrace OFF \
-macTrace ON \
-movementTrace OFF \
-channel $chan_1_
提取方法:
在路由层提取:
Node* thisnode = Node::get_node_by_address(src);
energy = thisnode->energy_model()->energy();
阅读(4523) | 评论(0) | 转发(0) |