NS2中802[1].11代碼深入理解—packet傳輸的流程_第1頁
NS2中802[1].11代碼深入理解—packet傳輸的流程_第2頁
NS2中802[1].11代碼深入理解—packet傳輸的流程_第3頁
NS2中802[1].11代碼深入理解—packet傳輸的流程_第4頁
NS2中802[1].11代碼深入理解—packet傳輸的流程_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、ns2中802.11代碼深入理解packet傳輸的流程來源: chinaunix博客 日期: 2009.07.04 16:50(共有0條評論) 我要評論ns2中802.11代碼深入理解packet傳輸的流程(轉載)轉自blog: 如何傳送一個封包(how to transmit a packet?)首先,我們要看的第一個function是在mac-802_11.cc內的recv( ),程式會先判斷目前呼叫recv()這個packet的傳輸方向,若是down,則表示此packet是要送出去的,因此就會再呼叫send(p, h).所以接著,我們跳到send(),此send( )首先會去檢查ener

2、gy model,若是目前這個node是在睡眠狀態(tài)(sleepmode),則把此packet給丟棄.然后會把handlerh設定給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的

3、長度,把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

4、_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 +plcpheaderlengt

5、h) * 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_);

6、/* 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,因此dur

7、ation為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

8、*)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-err

9、or() = 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_m

10、gt = 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

11、 + 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( ).接著,就指定一個uni

12、que sequence number給這個data packet.為了更清處的說明,底下把剩余的程式碼貼在底下./ * 這是在send( )內的程式碼 */* 若是目前backoff timer并沒有在 count down */if(mhbackoff_.busy() = 0) /* 此時channel又是idle */if(is_idle() /* 若是節(jié)點已經再等待defer timer,則讓defer timer繼續(xù),因此不做任何的設定.但是若沒有defertimer,就要根據802.11的規(guī)定,需要再等待一個difs和一個random time才能做資料的傳送,而這個randomt

13、ime是由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 timerexpires的時候,程式就會去呼叫deferhandler(),在deferhandler()中會先去呼叫check_pktct

14、rl(),但因為目前pktctrl沒有資料(回傳-1),所以會繼續(xù)去執(zhí)行check_pktrts().若是目前channel是idle的狀態(tài),check_pktrts()內的程式碼就會去設定傳輸狀態(tài)為mac_rtc,并且計算送出rts timeout的時間,算法為:timeout = txtime(phymib_.getrtslen(), basicrate_)+ dsss_maxpropagationdelay / 設定為2 us,可以參考mac-802_11.h+ phymib_.getsifs()+ txtime(phymib_.getctslen(), basicrate_)+ dss

15、s_maxpropagationdelay; / 設定為2 us,可以參考mac-802_11.h設定完后,就會去執(zhí)行transmit(pktrts_, timeout),把rts的packet送出去.送完rts后,我們必需等待cts,所以我們再回到recv()中的mhrecv_.start(txtime(p),這個程式碼主要是等待整個packet完全接收后就會去呼叫recvhandler(),而recvhandler()就會再去呼叫recv_timer(),若是判斷所收到的packet是cts,則再呼叫recvcts(pktrx_).在recvcts()中,因為已收到cts,則代表rts已傳

16、送成功,因此把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_

17、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

18、()又會再去呼叫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,然后再執(zhí)行一次backof

19、f */if(! is_idle() sendrts(ether_addr(mh-dh_ra);inc_cw();mhbackoff_.start(cw_, is_idle();return 0;/* 設定傳輸狀態(tài)為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_.getack

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論