免费预览已结束,剩余1页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
ns2中802 11代码深入理解packet传输的流程如何传送一个封包(how to transmit a packet?)首先,我们要看的第一个function是在mac-802_11.cc内的recv( ),程式会先判断目前呼叫recv( )这个packet的传输方向,若是down,则表示此packet是要送出去的,因此就会再呼叫send(p, h).所以接着,我们跳到send( ),此send( )首先会去检查energy model,若是目前这个node是在睡眠状态(sleep mode),则把此packet给丢弃.然后会把handler h设定给callback_.下一步,就是去呼叫senddata(p)和sendrts(ether_addr(dh-dh_ra).底下是senddata的程式码. (部份英文说明和程式码,会因为长度的关系而拿掉,所以读者最好还是拿原本的程式码做对照)void mac802_11:senddata(packet *p)hdr_cmn* ch = hdr_cmn(p);struct hdr_mac802_11* dh = hdr_mac802_11(p);/* 更新packet的长度,把packet的长度加上preamblelength (内定值为144 bits), plcpheaderlength(内定值为48bits), mac header length和ether_fcs_len */ch-size() += phymib_.gethdrlen11();/* 填入mac header中frame control内的子栏位值 */dh-dh_fc.fc_protocol_version = mac_protocolversion;dh-dh_fc.fc_type = mac_type_data;dh-dh_fc.fc_subtype = mac_subtype_data;/printf(.p = %x, mac-subtype-%dn,p,dh-dh_fc.fc_subtype);dh-dh_fc.fc_to_ds = 0;dh-dh_fc.fc_from_ds = 0;dh-dh_fc.fc_more_frag = 0;dh-dh_fc.fc_retry = 0;dh-dh_fc.fc_pwr_mgt = 0;dh-dh_fc.fc_more_data = 0;dh-dh_fc.fc_wep = 0;dh-dh_fc.fc_order = 0;/* 记录传送所需要花的时间,计算的方式(preamblelength +plcpheaderlength) * 8 / plcpdatarate + 剩于的封包长度(单位为bytes) * 8 / datarate_ */* 事实上,底下的这一行程式码是个浪费,因为底下又会针对是否为broadcast或unicast的封包,再计算一次 */ch-txtime() = txtime(ch-size(), datarate_);/* 若是这是一个unicast的封包 */if(u_int32_t)ether_addr(dh-dh_ra) != mac_broadcast) /* 再一次计算传送所需要花的时间 */ch-txtime() = txtime(ch-size(), datarate_);/* duration的意思是送出去此data packet之后,此次的通讯还需要占用channel所需要的时间,这个时间的长度为传送一个ack和一个sif的时间 */dh-dh_duration = usec(txtime(phymib_.getacklen(), basicrate_)+ phymib_.getsifs(); else /* 若这是一个multicast的封包 */ch-txtime() = txtime(ch-size(), basicrate_);/* 若是multicast packet,送出去此data packet之后,就算传送完成,不需要再等待ack,因此duration为0 */dh-dh_duration = 0;/*当mac header中的资讯都填完后,我们先把此packet暂时地存放在mac layer中的local buffer,等待适当的时机再传送出去 */pkttx_ = p;底下是sendrts的程式码. (部份英文说明和程式码,会因为长度的关系而拿掉,所以读者最好还是拿原本的程式码做对照)void mac802_11:sendrts(int dst)packet *p = packet:alloc();hdr_cmn* ch = hdr_cmn(p);struct rts_frame *rf = (struct rts_frame*)p-access(hdr_mac:ffset_);/* 检查要传送的封包大小是否是小于rtsthreshold或是不是一个broadcast的封包,若是的话,就不需要传送rts.若是在使用者所写的 tcl中没有指定rtsthreshold,则ns2会去读取ns-default.tcl的值,内定为0,因此若是使用unicast,则一定会送出去 rts */if( (u_int32_t) hdr_cmn(pkttx_)-size() uid() = 0;ch-ptype() = pt_mac;ch-size() = phymib_.getrtslen();ch-iface() = -2;ch-error() = 0;bzero(rf, mac_hdr_len);/* 设定rts packet中mac header的栏位 */rf-rf_fc.fc_protocol_version = mac_protocolversion;rf-rf_fc.fc_type = mac_type_control;rf-rf_fc.fc_subtype = mac_subtype_rts;rf-rf_fc.fc_to_ds = 0;rf-rf_fc.fc_from_ds = 0;rf-rf_fc.fc_more_frag = 0;rf-rf_fc.fc_retry = 0;rf-rf_fc.fc_pwr_mgt = 0;rf-rf_fc.fc_more_data = 0;rf-rf_fc.fc_wep = 0;rf-rf_fc.fc_order = 0;/* 把要传送的目的位址存放到ra */store4byte(&dst, (rf-rf_ra);/* 存放传送rts所需要花的时间, rts frame是用basicrate_传送 */ch-txtime() = txtime(ch-size(), basicrate_);/* 把传送端的位址放到ta */store4byte(&index_, (rf-rf_ta);/* 计算duration,计算的公式为: sif + t(cts) + sif + t(pkt) + sif + t(ack) */rf-rf_duration = usec(phymib_.getsifs()+ txtime(phymib_.getctslen(), basicrate_)+ phymib_.getsifs()+ txtime(pkttx_)+ phymib_.getsifs()+ txtime(phymib_.getacklen(), basicrate_);/* 把建立好的rts packet先暂时存放到pktrts_ */pktrts_ = p;看完senddata( )和sendrts( )之后,我们再回到send( ).接着,就指定一个unique sequence number给这个data packet.为了更清处的说明,底下把剩余的程式码贴在底下./ * 这是在send( )内的程式码 */* 若是目前backoff timer并没有在 count down */if(mhbackoff_.busy() = 0) /* 此时channel又是idle */if(is_idle() /* 若是节点已经再等待defer timer,则让defer timer继续,因此不做任何的设定.但是若没有defer timer,就要根据802.11的规定,需要再等待一个difs和一个random time才能做资料的传送,而这个random time是由0, cw_所决定的 */if (mhdefer_.busy() = 0) rtime = (random:random() % cw_)*(phymib_.getslottime();mhdefer_.start(phymib_.getdifs() + rtime);/* 此时channel若是busy */else mhbackoff_.start(cw_, is_idle();做完以上的事情后, send()已经完成了.然后,当defer timer expires的时候,程式就会去呼叫deferhandler(),在deferhandler()中会先去呼叫check_pktctrl(),但因为目前pktctrl没有资料(回传-1),所以会继续去执行check_pktrts().若是目前channel是idle的状态,check_pktrts()内的程式码就会去设定传输状态为mac_rtc,并且计算送出rts timeout的时间,算法为:timeout = txtime(phymib_.getrtslen(), basicrate_)+ dsss_maxpropagationdelay / 设定为2 us,可以参考mac-802_11.h+ phymib_.getsifs()+ txtime(phymib_.getctslen(), basicrate_)+ dsss_maxpropagationdelay; / 设定为2 us,可以参考mac-802_11.h设定完后,就会去执行transmit(pktrts_, timeout),把rts的packet送出去.送完rts后,我们必需等待cts,所以我们再回到recv()中的mhrecv_.start(txtime(p),这个程式码主要是等待整个 packet完全接收后就会去呼叫recvhandler(),而recvhandler()就会再去呼叫recv_timer(),若是判断所收到的 packet是cts,则再呼叫recvcts(pktrx_).在recvcts()中,因为已收到cts,则代表rts已传送成功,因此把 pktrts_ = 0和ssrc_=0,然后再呼叫tx_resume().在tx_resume()中,由于已成功的做完rts/cts,现在要准备送出data.这部份的程式如下所示/ * 若是pkttx_有资料要传送 */else if(pkttx_) if (mhbackoff_.busy() = 0) hdr_cmn *ch = hdr_cmn(pkttx_);struct hdr_mac802_11 *mh = hdr_mac802_11(pkttx_);/* 判断packet size是否小于rtsthreshold或者是不是broadcast */if (u_int32_t) ch-size() dh_ra) = mac_broadcast) rtime = (random:random() % cw_) * phymib_.getslottime();mhdefer_.start(phymib_.getdifs() + rtime); else /* 若是unicast且packet size大于rtsthreshold,则会等待一个sifs后,再把data packet送出去 */mhdefer_.start(phymib_.getsifs();等到defer timer expires后,又会呼叫deferhandler(),而在deferhandler()又会再去呼叫check_pkttx(). check_pkttx()的程式码如下:int mac802_11:check_pkttx()struct hdr_mac802_11 *mh;double timeout;assert(mhbackoff_.busy() = 0);if(pkttx_ = 0)return -1;mh = hdr_mac802_11(pkttx_);switch(mh-dh_fc.fc_subtype) case mac_subtype_data:/* 若是目前的channel是busy的话,就需要增加contention window,然后再执行一次backoff */if(! is_idle() sendrts(ether_addr(mh-dh_ra);inc_cw();mhbackoff_.start(cw_, is_idle();return 0;/* 设定传输状态为mac_send */settxstate(mac_send);if(u_int32_t)ether_addr(mh-dh_ra) != mac_broadcast)timeout = txtime(pkttx_)+ dsss_maxpropagationdelay / 设定为2 us,可以参考mac-802_11.h+ phymib_.getsifs()+ txtime(phymib_.getacklen(), basicra
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 工程老坟搬迁协议书
- 注册公司签合同范本
- 油漆房加工合同范本
- 法治社区共建协议书
- 工程人员劳动协议书
- 扶梯拆装协议书范本
- 扶梯护栏购买协议书
- 扶贫项目履行协议书
- 承包付钱协议书模板
- 承包学校经营协议书
- 2025内初班语文试卷及答案
- 园林机械维修培训知识课件
- 榨季运输安全培训简讯课件
- 2025年-网络安全等级测评报告模版(2025版)新版
- 初中重点化学方程式每日一练小纸条【答案】
- 移动应用开发白皮书方案2025
- 气管切开患者护理指导方案
- 文化传媒公司运营管理指南
- 110kV变电站运行记录表填写标准
- AI在港口和船舶制造业的应用现状与发展分析
- 社会科学研究方法 课件全套 第1-12章 导论-撰写研究报告
评论
0/150
提交评论