</div><!--end: blogStats -->
</div><!--end: navigator 博客導航欄 -->
NS3中一些難以理解的常數
摘要:在NS3的學習中,PHY MAC中總有一些常數,需要理解才能修改。如幀間間隔等。那麼,本文做個簡單分析,幫助大家理解。針對802.11標準中MAC協議。
void WifiMac::Configure80211b (void) { SetSifs (MicroSeconds (10)); SetSlot (MicroSeconds (20)); SetEifsNoDifs (MicroSeconds (10 + 304)); SetPifs (MicroSeconds (10 + 20)); SetCtsTimeout (MicroSeconds (10 + 304 + 20 + GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2)); SetAckTimeout (MicroSeconds (10 + 304 + 20 + GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2)); }
304是怎麼來的呢??
1、PHY
採用DSSS,1Mbps模式下。在802.11-2012中,17.2.2.3節中,有PPDU format規定了幀格式。如下圖:
其中,大家比較關心的2個參數就是 PLCP Preamble 和 PLCP Header,分別爲144bits和48bits。也就是192us,英文爲192 MicroSeconds。
計算時間的相關代碼,在NS3中 wifi-phy.cc中,代碼如下:
uint32_t WifiPhy::GetPlcpHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble) { switch (payloadMode.GetModulationClass ()) { case WIFI_MOD_CLASS_OFDM: { switch (payloadMode.GetBandwidth ()) { case 20000000: default: // (Section 18.3.3 "PLCP preamble (SYNC))" and Figure 18-4 "OFDM training structure"; IEEE Std 802.11-2012) // also (Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012) // We return the duration of the SIGNAL field only, since the // SERVICE field (which strictly speaking belongs to the PLCP // header, see Section 18.3.2 and Figure 18-1) is sent using the // payload mode. return 4; case 10000000: // (Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012) return 8; case 5000000: // (Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012) return 16; } } //Added by Ghada to support 11n case WIFI_MOD_CLASS_HT: { //IEEE 802.11n Figure 20.1 switch (preamble) { case WIFI_PREAMBLE_HT_MF: // L-SIG return 4; case WIFI_PREAMBLE_HT_GF: //L-SIG return 0; default: // L-SIG return 4; } } case WIFI_MOD_CLASS_ERP_OFDM: return 4; case WIFI_MOD_CLASS_DSSS: if (preamble == WIFI_PREAMBLE_SHORT) { // (Section 17.2.2.3 "Short PPDU format" and Figure 17-2 "Short PPDU format"; IEEE Std 802.11-2012) return 24; } else // WIFI_PREAMBLE_LONG { // (Section 17.2.2.2 "Long PPDU format" and Figure 17-1 "Short PPDU format"; IEEE Std 802.11-2012) return 48; } default: NS_FATAL_ERROR ("unsupported modulation class"); return 0; } } uint32_t WifiPhy::GetPlcpPreambleDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble) { switch (payloadMode.GetModulationClass ()) { case WIFI_MOD_CLASS_OFDM: { switch (payloadMode.GetBandwidth ()) { case 20000000: default: // (Section 18.3.3 "PLCP preamble (SYNC))" Figure 18-4 "OFDM training structure" // also Section 18.3.2.3 "Modulation-dependent parameters" Table 18-4 "Modulation-dependent parameters"; IEEE Std 802.11-2012) return 16; case 10000000: // (Section 18.3.3 "PLCP preamble (SYNC))" Figure 18-4 "OFDM training structure" // also Section 18.3.2.3 "Modulation-dependent parameters" Table 18-4 "Modulation-dependent parameters"; IEEE Std 802.11-2012) return 32; case 5000000: // (Section 18.3.3 "PLCP preamble (SYNC))" Figure 18-4 "OFDM training structure" // also Section 18.3.2.3 "Modulation-dependent parameters" Table 18-4 "Modulation-dependent parameters"; IEEE Std 802.11-2012) return 64; } } case WIFI_MOD_CLASS_HT: { //IEEE 802.11n Figure 20.1 the training symbols before L_SIG or HT_SIG return 16; } case WIFI_MOD_CLASS_ERP_OFDM: return 16; case WIFI_MOD_CLASS_DSSS: if (preamble == WIFI_PREAMBLE_SHORT) { // (Section 17.2.2.3 "Short PPDU format)" Figure 17-2 "Short PPDU format"; IEEE Std 802.11-2012) return 72; } else // WIFI_PREAMBLE_LONG { // (Section 17.2.2.2 "Long PPDU format)" Figure 17-1 "Long PPDU format"; IEEE Std 802.11-2012) return 144; } default: NS_FATAL_ERROR ("unsupported modulation class"); return 0; } } double WifiPhy::GetPayloadDurationMicroSeconds (uint32_t size, WifiTxVector txvector) { WifiMode payloadMode=txvector.GetMode(); NS_LOG_FUNCTION (size << payloadMode); switch (payloadMode.GetModulationClass ()) { case WIFI_MOD_CLASS_OFDM: case WIFI_MOD_CLASS_ERP_OFDM: { // (Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012 // corresponds to T_{SYM} in the table) uint32_t symbolDurationUs; switch (payloadMode.GetBandwidth ()) { case 20000000: default: symbolDurationUs = 4; break; case 10000000: symbolDurationUs = 8; break; case 5000000: symbolDurationUs = 16; break; } // (Section 18.3.2.3 "Modulation-dependent parameters" Table 18-4 "Modulation-dependent parameters"; IEEE Std 802.11-2012) // corresponds to N_{DBPS} in the table double numDataBitsPerSymbol = payloadMode.GetDataRate () * symbolDurationUs / 1e6; // (Section 18.3.5.4 "Pad bits (PAD)" Equation 18-11; IEEE Std 802.11-2012) uint32_t numSymbols = lrint (ceil ((16 + size * 8.0 + 6.0) / numDataBitsPerSymbol)); // Add signal extension for ERP PHY if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM) { return numSymbols * symbolDurationUs + 6; } else { return numSymbols * symbolDurationUs; } } case WIFI_MOD_CLASS_HT: { double symbolDurationUs; double m_Stbc; //if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us //In the future has to create a stationmanager that only uses these data rates if sender and reciever support GI if (payloadMode.GetUniqueName() == "OfdmRate135MbpsBW40MHzShGi" || payloadMode.GetUniqueName() == "OfdmRate65MbpsBW20MHzShGi" ) { symbolDurationUs=3.6; } else { switch (payloadMode.GetDataRate ()/ (txvector.GetNss())) { //shortGi case 7200000: case 14400000: case 21700000: case 28900000: case 43300000: case 57800000: case 72200000: case 15000000: case 30000000: case 45000000: case 60000000: case 90000000: case 120000000: case 150000000: symbolDurationUs=3.6; break; default: symbolDurationUs=4; } } if (txvector.IsStbc()) m_Stbc=2; else m_Stbc=1; double numDataBitsPerSymbol = payloadMode.GetDataRate () *txvector.GetNss() * symbolDurationUs / 1e6; //check tables 20-35 and 20-36 in the standard to get cases when nes =2 double Nes=1; // IEEE Std 802.11n, section 20.3.11, equation (20-32) uint32_t numSymbols = lrint (m_Stbc*ceil ((16 + size * 8.0 + 6.0*Nes) / (m_Stbc* numDataBitsPerSymbol))); return numSymbols * symbolDurationUs; } case WIFI_MOD_CLASS_DSSS: // (Section 17.2.3.6 "Long PLCP LENGTH field"; IEEE Std 802.11-2012) NS_LOG_LOGIC (" size=" << size << " mode=" << payloadMode << " rate=" << payloadMode.GetDataRate () ); return lrint (ceil ((size * 8.0) / (payloadMode.GetDataRate () / 1.0e6))); default: NS_FATAL_ERROR ("unsupported modulation class"); return 0; } } Time WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txvector, WifiPreamble preamble) { WifiMode payloadMode=txvector.GetMode(); double duration = GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble) + GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble) + GetPlcpHtSigHeaderDurationMicroSeconds (payloadMode, preamble) + GetPlcpHtTrainingSymbolDurationMicroSeconds (payloadMode, preamble,txvector) + GetPayloadDurationMicroSeconds (size, txvector); return MicroSeconds (duration); }
在函數CalculateTxDuration中,duration的計算方法。
那麼,假如你開啓4次握手機制,那麼rts的duration如何計算呢?
也就是當你生成pacp文件,用wiresharp打開時,看到rts幀中,那個duration是怎麼得到的呢?
如下圖中17342 是怎麼得到的呢?
你需要知道應用層的包是如何封裝的,這涉及到計算機網絡的知識。這裏以上面的包大小舉例說明,packet =2000bytes.
上圖中可以看到:data—>udp(8)—>ip(20)—>llc(8)—>mac (28)包封裝過程
ip和udp封裝包頭大小,一般計算機網絡書中有介紹。llc 這個沒搞懂爲啥是8個。mac數據幀可以看下圖:
一共40字節,但是地址4,qos,ht不用。ns3中使用的是non qos mac。
好了,我們開始計算,但是還需要看一個代碼在mac-low.cc:
void MacLow::SendRtsForPacket (void) { NS_LOG_FUNCTION (this); /* send an RTS for this packet. */ WifiMacHeader rts; rts.SetType (WIFI_MAC_CTL_RTS); rts.SetDsNotFrom (); rts.SetDsNotTo (); rts.SetNoRetry (); rts.SetNoMoreFragments (); rts.SetAddr1 (m_currentHdr.GetAddr1 ()); rts.SetAddr2 (m_self); WifiTxVector rtsTxVector = GetRtsTxVector (m_currentPacket, &m_currentHdr); Time duration = Seconds (0); WifiPreamble preamble; //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2 if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ())) preamble= WIFI_PREAMBLE_HT_GF; else if (rtsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT) preamble= WIFI_PREAMBLE_HT_MF; else preamble=WIFI_PREAMBLE_LONG; if (m_txParams.HasDurationId ()) { duration += m_txParams.GetDurationId (); } else { WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr); duration += GetSifs (); duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxVector); duration += GetSifs (); duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble); duration += GetSifs (); duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector); } rts.SetDuration (duration); Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble); Time timerDelay = txDuration + GetCtsTimeout (); NS_ASSERT (m_ctsTimeoutEvent.IsExpired ()); NotifyCtsTimeoutStartNow (timerDelay); m_ctsTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::CtsTimeout, this); Ptr<Packet> packet = Create<Packet> (); packet->AddHeader (rts); WifiMacTrailer fcs; packet->AddTrailer (fcs); ForwardDown (packet, &rts, rtsTxVector,preamble); }
公式就是上面這個代碼中提取出來的。sifs查這個802.11-2012中上圖
duration += GetSifs (); 10
duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxVector); cts:14*8+192=304
duration += GetSifs (); 10
duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble); 2064*8+192=16704
duration += GetSifs ();10
duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector); ack:14*8+192=304
duration = 10+304+10+16704+10+304=17342
結果符合wiresharp中那個duration。
</div>
<div class = "postDesc">posted @ <span id="post-date">2014-11-28 22:31</span> <a href='http://www.cnblogs.com/khldragon/'>khldragon</a> 閱讀(<span id="post_view_count">...</span>) 評論(<span id="post_comment_count">...</span>) <a href ="https://i.cnblogs.com/EditPosts.aspx?postid=4129518" rel="nofollow">編輯</a> <a href="#" onclick="AddToWz(4129518);return false;">收藏</a></div>
</div>
<script type="text/javascript">var allowComments=true,cb_blogId=64327,cb_entryId=4129518,cb_blogApp=currentBlogApp,cb_blogUserGuid='aef037c4-44ea-de11-ba8f-001cf0cd104b',cb_entryCreatedDate='2014/11/28 22:31:00';loadViewCount(cb_entryId);</script>
</div><!--end: forFlow -->
</div><!--end: mainContent 主體內容容器-->
<div id="sideBar">
<div id="sideBarMain">
公告
<div id="calendar"><div id="blog-calendar" style="display:none"></div><script type="text/javascript">loadBlogDefaultCalendar();</script></div>
<div id="leftcontentcontainer">
<div id="blog-sidecolumn"></div><script type="text/javascript">loadBlogSideColumn();</script>
</div>
</div><!--end: sideBarMain -->
</div><!--end: sideBar 側邊欄容器 -->
<div class="clear"></div>
</div><!--end: main -->
<div class="clear"></div>
<div id="footer">
Copyright ©2016 khldragon
(function(){ ("input[name=article_support]").click(function(){ ("textarea[class=comment_textarea]").val("文章不錯,支持一下!");
;
}); ("input[name=article_pass]").click(function(){ $("textarea[class=comment_textarea]").val("飄過~~"); ; }); });