From 2bd74fdbd7c33fc89f7b28fb563db07fca7c836e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Mon, 3 Dec 2018 21:18:05 +0100 Subject: [PATCH] wifi: Add threshold-based preamble detection model --- CHANGES.html | 1 + RELEASE_NOTES | 1 + .../hwmp-proactive-regression-test-0-1.pcap | Bin 7313 -> 7313 bytes .../hwmp-proactive-regression-test-1-1.pcap | Bin 11682 -> 11682 bytes .../hwmp-proactive-regression-test-2-1.pcap | Bin 13453 -> 13453 bytes .../hwmp-proactive-regression-test-3-1.pcap | Bin 11835 -> 11835 bytes .../hwmp-proactive-regression-test-4-1.pcap | Bin 7466 -> 7466 bytes .../hwmp-reactive-regression-test-0-1.pcap | Bin 6339 -> 9930 bytes .../hwmp-reactive-regression-test-1-1.pcap | Bin 11396 -> 8614 bytes .../hwmp-reactive-regression-test-2-1.pcap | Bin 7063 -> 3613 bytes .../hwmp-reactive-regression-test-3-1.pcap | Bin 9169 -> 5649 bytes .../hwmp-reactive-regression-test-4-1.pcap | Bin 4844 -> 3385 bytes .../hwmp-reactive-regression-test-5-1.pcap | Bin 2271 -> 2180 bytes src/wifi/doc/source/wifi-design.rst | 18 +- src/wifi/model/interference-helper.cc | 21 +- src/wifi/model/preamble-detection-model.cc | 36 +++ src/wifi/model/preamble-detection-model.h | 58 ++++ src/wifi/model/spectrum-wifi-phy.cc | 2 +- .../threshold-preamble-detection-model.cc | 65 +++++ .../threshold-preamble-detection-model.h | 63 +++++ src/wifi/model/wifi-phy.cc | 152 ++++++++--- src/wifi/model/wifi-phy.h | 41 ++- src/wifi/model/yans-wifi-channel.cc | 2 +- src/wifi/test/preamble-detection-test.cc | 254 ++++++++++++++++++ src/wifi/test/wifi-test.cc | 10 +- src/wifi/wscript | 5 + 26 files changed, 669 insertions(+), 60 deletions(-) create mode 100644 src/wifi/model/preamble-detection-model.cc create mode 100644 src/wifi/model/preamble-detection-model.h create mode 100644 src/wifi/model/threshold-preamble-detection-model.cc create mode 100644 src/wifi/model/threshold-preamble-detection-model.h create mode 100644 src/wifi/test/preamble-detection-test.cc diff --git a/CHANGES.html b/CHANGES.html index b99bbf114..f78fbb808 100644 --- a/CHANGES.html +++ b/CHANGES.html @@ -58,6 +58,7 @@ us a note on ns-developers mailing list.

  • A new attribute WifiPhy::PostReceptionErrorModel has been added to force specific packet drops.
  • +
  • A new attribute WifiPhy::PreambleDetectionModel has been added to decide whether PHY preambles are successfully detected.
  • New attributes QosTxop::AddBaResponseTimeout and QosTxop::FailedAddBaTimeout have been added to set the timeout to wait for an ADDBA response after the ACK to the ADDBA request is received and to set the timeout after a failed BA agreement, respectively.
  • diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 4927b8468..bfd5857af 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -23,6 +23,7 @@ requirements (Note: not all features available on all platforms): New user-visible features ------------------------- +- (wifi) Preamble detection can now be modelled Bugs fixed ---------- diff --git a/src/mesh/test/dot11s/hwmp-proactive-regression-test-0-1.pcap b/src/mesh/test/dot11s/hwmp-proactive-regression-test-0-1.pcap index 01a3809b5f600d2bec660cd4c5b47be721b3bcad..50ff54e2df92bdb1c0049786f4b556501563580a 100644 GIT binary patch delta 120 zcmbPeIni>1Iw#YjOOpd6CD@o47#NtYOwN;3n4HeJfJx}eWCJOPsMF`kr#TcRyK~tv z&H4glN=}}~<;=9;7f2f`NZZLt+_6kIf5SCw|1;T7N@4O`?gh+${<2SQWRqs{`afAu LT48f7kB9&Owbdou delta 120 zcmbPeIni>1Iw#ZWOOpd6CD@o47#O&(OwN;3n4HeJfJyqwWCJOPsQ2f|r#TcRyK~tv zE&c*zN=}}~<;=A57f2f`NZX}J+_6lLe#12!_%qp0N@4O`?gh-O|JWxtvPm-q|DUWU Lt+2V4M??Ssx#cB5 diff --git a/src/mesh/test/dot11s/hwmp-proactive-regression-test-1-1.pcap b/src/mesh/test/dot11s/hwmp-proactive-regression-test-1-1.pcap index 752e3175fc014887768848405c99318a6eadbcd8..54714b633948a9b992f25fda9e7bb610a48c7e45 100644 GIT binary patch delta 228 zcmZ1!y(oIaQC=pKGm{H>geS|Y@J@ctYs0+v0{g@V;*%Y?S(sBVu}{7zDnB`yZvj*3 zrOEH5CD@r57#My6g*S@HPj=>Cz-)JgeR2ScI2%a((C5jC0+N$u1e_VACMO8QG8KOX z3!LL-pL}1yhS~Zj%w(pNUqCx0Cx-|+GnM=T84NbS^EcQfwTirxuM65Rv;F~_4YqUt zU-rop#pNdl3oT$e|9A3v9vNoGf9#VBCFCa?3ol@9`;Sn{$jC7{P*Q%gut>io0B1Q# A6951J delta 228 zcmZ1!y(oIaQC=q7Gm{H>geS|Y@J@ctYr}l(0{g@V;*%Y?S(x)Ku}{7zDnB`yZvj)? zrOEH5CD@r57#Nr?vrpbACO_Gke*v@m752#iEaGe+@zb9tCkjYTmJx7fRGyq55X)5a z6)bR$n|<e|a(@Bsl$;zQ=*(363uG|ZfS})Cm((iqPQET^!_4;wY&O`= z6Mxw!PZXD*94xee>Bis5=Xqq9z5cOJE|id;Y%IKhx&J>xDHkKh BNWTC8 diff --git a/src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap b/src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap index e59c83eccfd0aba392ac76ce961a3a868119ac80..156033813d030cb9ce739f95a896027e28c86482 100644 GIT binary patch delta 271 zcmeCp?9JSe!q2(oG&_SI0|SHK!sL8Cg~@dS3z#Nem~5yI5ske#*HmJf+@dHiIoU$QhKcVd$P%#R zFhsYZc&t%oNOUt!zBI_WC>XE z4P25@L2~jI5gW#plRt{cGG3a@FB;3l`fu__sJ+4eC-WOBOkN|pfGPR^F8Sf;+SlNSohFg-mt zdA^+FWIJxQ$zJ>mnZBNzJdsa$k^m=D<@w2dG76Km1r{*vy#Q94dTDZ=tioh&!3B)P zlh+8wGVTPDQj=ALoEeiQX9&eI6@7y7}Enu?zHd&8Da`IGeXU0d9Z*s>n&;Jfr$aMKTP*P!X8IKL; pzaQ)jen2z*CLiRIoP34HhS7GiAg?TAy7}Ensr`Hd&8Da`IGeXU5l)Z*s>nulNpE$aLpBP*P!X8IKJo p`%iWTKcJa@lMix9PQJop!{|0ykXM$mX|g`=LB>g&Kk{1g0|4y&ExrH% diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-0-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-0-1.pcap index b07cceab6ef4d4919fb9b747ee5f25422f7b8506..207252f5a23f00c3b8dc6f3009ea3f818e533a62 100644 GIT binary patch literal 9930 zcmb`MZEO@p7{_PsdhMMOyNflb!L)^z_C(q%5R@Rcd}!hqlqLj4PbonYjW1~-B&2>h zi}3|1xoToGF{UQIgp`D~Rtjw)B_<|HFxS`sS|ew*QfVaJsGxqZ&NI8)o6F7Z+;*N# zcDr{o&u^cd{onJlo%mwl!vHBF?lwP9$g|D|>pw#7XXmgd*gnrUc0x$VJ;EH=W+)tK zc*)Y+t6~qfK7WAhEqdYUeb2zRu$dEK1YJ({4OSmtV(>x2T7U&Fpq)sF(p70Du5vzPH$BR}D> zdZ+MMAN`ESdh-`N*4}ABe^O1fDfI`xRa+I?e-&s_RrsMbUcsbQ&S27({Dw)pfl8aY zis{?=*>ENuNEMREP6q)e9Y7@6`nzB(6@-Vebxp(g;GBlBWoa0n`$J-!71Dde1q-k+ ze(%CBXp$M{kKmjBl%TVsuE%l?{Iy8qAoI?;NtHj7q<_4Q--lOT2iDQ3M4wp&#+WkZ z0EZAbny+V~VS;_mEu(tK_(L1mh`?Q1cAUbX8owl@W#H)Zri_x#$XkCY78YTG>iW+MQLHv}M(pw0}@(*H>ZscBw|_ zm8C%`E5w5s><|y~8mtwJrGoG@C+%*Zcl=VxR8UpN4_Vx9 z-S0Rh(4-pjL#rLeq*ae#(u`3|TKQ>A8a;zav({2Y9*fcTu{>%E1)Aex9^>+Tgevk_ zlMl&FKPu3qlJi4L?Zl*wJcda-`#2`;SR9jf?CJNgtG@lHk1S6Nr{rVl3-wbB0J z=L%w(ag|>QI=*_Jk`)HOl&xNpTIr60Smt4sUp>_PptCSmm(XOmDbijkC*3BM@d^qo zLf|ed87=2Ia}JCiV59DHmcJD5qwrEZD7=CfUy2tw|J?!BT}LEW;(o(uBO6sTus-f; zGAYocKe{m=wBENcXFitPlIKo!jI-yGXbF|^+Lu{sZ0l`_UA#{^eg3T9-5ho$0=~sISV=Xs? z!ci(A5>WM@b~FOd3{#*YeZ%+t)msBAY0ij)laABt*2pMOG1Y@ZnJd8g% lsbSo9O2hc@u!ixj5e?%VqZ-EQe~-ojEkAU#=i;4){s$%VlO6y7 literal 6339 zcmb`LYiJWe5P)ZsCQVdqPlSq~#ur+veb}mqulhsqhl)iJkqY&N)(2RnAQd$zh=@x2 z%RfHq4-p?oD=Ok21L_}tXbVL}rN;LQX-{hf5$nueF4-fS+iS81ce&i|d^0u&>mIj?av)EHrGys7d8Z>vrygJ$bvf z?A=CB=`gxN3RWTSLw!}OP5v;*lsL$DBg(wQ{2 zwfqTVH$wp$BenFF;T!T91AIQW(a&gp0CZi1wBh(mXBVFQ;2df_iLJK7b?`fUXpNF^ zxH>4{u+(U&aRNTZ$FN4~>lRqHlVr(y5ZA|g@(@$q^DUH02T~7-I@5tKkq#)5 zZ1^q+OC7>RIM9=W@af(hgabcv5PtnrBJ2q1t)jtv7{=!$cTf)sXO7@&`y^;b)O9iE zlV4d1`%yb{h$??JLwjc_pNCssC)VX+iMKlnjF>X!5C?#+#<5g1jNsk#Rs9;x@QuDJLcIdIsz$R6;gCp_Cn$aT$oy8*y>)Rxu8#B9gq~ZceFz< zU_ycCM+Z&m6~V-x6t;J?SK;lL>9ZCt!c>)&FqPltV^y);2IjK`*wfuhh-I8nd0Y&P zi%UGQYNv(y3Q%2^tp6P5EN4`c;UXl9f3YUZOVnhf*VOWGdhFmVYTZB6t@ZCbRnfmv z^a&c)3R)D{%u-cw=zxl*<=E5RxWqE9sf-(kn%}FHEQ*TeOqE`}&=9Nj#8NLhu$JP@ zN*1k$`BmkNg{=MV4o@tjR%NdU>nz#pjddU+%StlAHdepP8>$G_Ah9#5Cp)1hXEa*tTuNtJG-Wmfdh z3_(%p4sucSW0^$Qp=ey3C7I8vA4so$6wa*I8Z2wl>OM#8chSqN$U*o>We&m@t0cl+ zEpiKmGh1ZXED74HMf|gK5Pm8OOLydMahaXYymgLbQrsdTbb^Oht*@YtFQMce_BYC4 zuhP{m8xT!h??;&#Z{m2j_f=wDSPc@l&t?JN&{2? diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-1-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-1-1.pcap index 943faa860d28c9ecfd77af5de6f63f9d39b01c27..edf8f243a09d95c58bf06b33fea472fed332b837 100644 GIT binary patch literal 8614 zcmb`MZEO@p7{_P!dcC_qXsa=5Ok)YvQiG%j6(O}04T%^@nrKLXvm6j3jRFNy13}}3 zFJ>F7hc7gKA@!vuE08n>LxhkJ2$IT6swq~enlozX5rq2o#kcxAv%7b*?(ELq&1|yQ zz0UrB_w3AnW}cZHJN@yy2B{+MF+EL4xAVoEAfyeh@yx@5k&TSxg4<0_Z#mTzlB>kU#|Kh?ETCSxG%WeOgqX{in4lVtUPTHD(b<$Q( z>!hVgs?_n7>un9yNqfLZk^8|;c!~$54pI}dUDcb2;rO!%PWzY@>B0f>2 z@XIIS3gRQxD&jT6lk_(lhAUPG3Z4V>4UxhO*lr*4i@jdd7UzPa0`IQ5m24y0IDgy82#mpPi-Zz`sp zx}uYo{zfOQ{ac;1Yv1Xl9n0&a&Ay)W52Us?9Jgh?1F7K*q-cl*Af5$(@f?Gb9ZZI$ zFN@F~yA1MZ1CqtXjDX_08(dsMuZ4);zo{T@|3yK3=vM{t3%@CdfBwBfaSUqPOwge9 zf-_DGla&|ev(^b4qmi|7PT=@u=lO{qa;(rAiM1bCzVXYmS~w{kzc403@UyRxqq&}{ zn3lUoCvC^QI%(UQbkf$&)k$k>)=9ID$kraCq#*J&O{Mv)r_cRxtaP5&V z!*b1MIGWIM<%Vg)bGvePasZJHJv8pC4BcKMP4`aiv#og_)3J`o#8(=FCN&EP}!`VW%M2RPTV; zm)$TKmJUrQpg#ez7>#>_CahN_JAu@kiSwdhKZRQ{Axpkus->2>A`^|0!NPLji9oQR*^#QPanYB%^8@D<~WxM*=aS6evT-7fa&lm?w^HA#cz~W||$3nxj z21bh*_YR@-_8@LlId4pmH6{8b7B`k2d`<9Fo?kjy##0>!n%KSgTaB*^p2|~$gF#Pa zEa~+=)eLU`Xw>aw6|yGwad9cKa&PKmZGB50Yw6pvtbdqV9|rVLu38C|dyQ$C6b*_UAM0?tz#<;IfwfDo zaL^)lZjKhoF5|>P6NHI76vR(1R}j}fq98UNRS=)ARGfm^HX##myIdB&`(N

    By!& uC<#xYk#*)%Sw7idaLtZ}utx?IUjngsWWZ7jR=D9|PSL{LH{j0jF#iKHs|c0= literal 11396 zcmb`Ne{2**6vt=xdcCVOv>H(pLaed;CFmld473LPdohaJDg_L1KZ_AYi-@ z6LXDCDq{V|q}4>?AqX)<3`)`f0V`3_LQqgFl|LvFMAXD!wZ1pAyEn_u?(FT(CVSoM z?EB1{neV=NGkYfwfBdda@`!nijS|HtsCWNLdoSqOZ=;nw(LKZw5P^Y z(h{T~`{0M}w`H12+8n)r%mg{%DGo|?q$t8v)e(ze{Fw_UJH|&iV`0NQjL(NLKA0Dx z=7Z4?#{2Ta7{>w{W53JiwMH^9shAFpBRX*N8nQAe*LlsDi;`sI(Ct!|?#r)sQjomU z7c0{(^D9NlCQS9kdg*&tR+IvwjpU7lKh|zwIp%IgG5V`p8c4CP2*J;tKX5ejxd}`= zbVemD@uNyw%}*+6W#?4VuKui&R&hD*45UmOhT2m0K&l&o6a`Ta#^d2Ho+sg?2Q|ae zH$`ZhT>5yl4#{FAC7|)-E1X|Kt$7&l|1E^^lHWrZ_g@QP-1$cczK%;MX2hzK1#YglmtX z93;2;2uBl2E*IMDqbg|^j;W-*H=vT1Jg$;<=_{4A-fy@_D^$o;eqKXSv9$+YHGIn% z3kBg}d}=U+@hhi77)MWsF#Z&>P;0T4Yn!i$l1?@$8Pkb8g~g=26~ zfzrT^j*8IKQAAgr<3XclxhHo+O-+*pTQ@cl$R{z(=?UHWZUvfH73lW?C^dUX zys=ZR6#)z$5Nr24yVD%i^XN*I)wE?Q#}dXJ|E$H+)Up07Q^z_oLmewMQyuHdEOo5Q zvjy8vHvQS=Oq3dnohYbLFm{()Q#mJXVOXxyWG^?c7AClwdpVj=aJkTG=Y(kX6JYG# z>_I5C)>WY$T`*TAZO=TFw1@9gNh_;TNxSuaZh(d2YvgkR3~g+3Ma7-tjfF$#Vf?{- zuI8MLt3w#~J`lpVt0si;)3pJOamy+VFKW$cDFxr1ueg%hz{1C%#CtkLR_1lr4H6dA z^4qnM(@#oScyoHc%&(MIP@nL{%2dnz>ekA>Y?ZPwhf5!m`PHX2yuHR3E3-xB*Iun{ z(FR|vSML%$z^vEV&SX>`p;;<}t=tYYN06l)EFFeYQ!`d7!)h_cxu2#oc`m6;)JSEJ zHL+Bs-!p*b?)O$Gwfr`NLqNZGKsslwAIuPE>u+0>%1+(b=ubqMqSd{(O;P9OuL@aX zqO3Du_x&x(Is>w;;XuM~os!y_&o;Z`#MiFSvSHQ?GHeKqfYr^% z!U+5rm2Iw|@ylTBh=tS)OOK1twun=rb9>(T*5)x9Csqp3me=2{;=DGM<=5+BFn0Gk zvt72_DAzMPwt|b^OT7XpPs6ifrqU_+?p!w3=>x5uP$Fk#PRjgh)JLXmld}E??G*{i diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-2-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-2-1.pcap index 5f02ba69d0d76a48ee09c56352ab7b5fe612b1f6..6b623819c49bbd8c116df9e29a7a3a84df31102a 100644 GIT binary patch delta 647 zcmbPkK38Ug5ff9~o5>rQg}GT7fPe{zf4rY;$R<4bCnN9VA|`P*kPzc%B%ySs`QDRn zGs&15^)WH%0%bw?0)q{Z1OiSl$pIlBFz_=MvE-%}XOyxtGchnSm@rJ{We(vyf0%>8 z4yeR#@>xmA$<53(_x-`o?~($pFEgddI7;^xddl3*Gvq z?C00uY^IJIlXr7iGnw83`~Lx_22@p9%ma-4z!+p^VC3Ktl29@5NXRK7 zovS{QK@!K%5FvZwKlE#al*4x{Q7A*~fG>n(C(hUgj~^7zR2wsH;>>VmjCqG-;nKrJx5=?KKn*Z?A8%0?J#gx=-Fm@JisE>10D7aJ{^}SX} z>*!ZWTliKbZSb8++L`w%Y2A7na*2Vlvs{*Z;Lt){+X4+PZC0S!4iPaaO4(#gC>N#t z5Tz^`H-oXWUjrhvZQXS7>)0oOUtWzXKc`_l@Ffl7vtQFN4t^V~%ipgF&3{z|E#1Qq zvWyDHFcg2+4AQdm>!mD=S$dBwiic=jO@k+v5s~>7rV(w2l!XtWKalygjCNeu>xm`r zuWEWP_n;?MEi8OV87K}4+n4(~%dNH$Ccm@oE|8bF7IPW>rmR02seV5qeFkK;S5Ygl zBxb%X1rPdUn^I=JgS6{FOY)mlV{LF1WeXE-eTnx)nkepzz;4v=1}48R;*W2lAd9T# zSP8#PN8-Bo&gxyGj&*dcI@YswD#u0#n)BE!s8Q#4`FeG%;tlFpQ#Nw_DGZTOD$}~T z2Z#zRs^w@x1*SqP+oY0Kx>+S{dYwwzgnE^3Y#T`q4Xu>g=f(_b*f z_;#`&w>Q(3pveKe3X|)&b(n7jGfqCpFAruP4MDIEg(BGd!w~H2;czx%!)8O?JuFPK z&P;wU=r#F*kPq{#sf?2yloePQU(K_d9H6K;*+EK;Re+I8#tqE7si4NFFiFvy(O|NV zqBpApW0rC(P(pR`K}99j0LHE#DPU!sN@|P=lMR%-84D)YD0#CsFur21ncSeHI{BlL g66*v;uA9wZb(YF%ObZw%Cn|ffZeaBKJ_#fU0MfQtR{#J2 literal 9169 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 F{s4(Qaw-4- diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap index 1e515a1aba46750f6332c2004e7e01ee90fd245e..a9a2d8af6f09d9d867bc420cb5ceda21edef05c6 100644 GIT binary patch delta 42 ycmcaF*dn;WikY!tvNf|Tyf3)HikWfJWNT(w#yyiGnQfT*6DLP8TW`L^9K*=Y!oa|gqR%-sy%S&n diff --git a/src/wifi/doc/source/wifi-design.rst b/src/wifi/doc/source/wifi-design.rst index 0171c2e49..e6cc85ddf 100644 --- a/src/wifi/doc/source/wifi-design.rst +++ b/src/wifi/doc/source/wifi-design.rst @@ -175,7 +175,6 @@ The following details pertain to the physical layer and channel models: * 802.11 PCF implementation currently assumes a DTIM interval equal to the beacon interval * Authentication and encryption are missing * Processing delays are not modeled -* PLCP preamble reception is not modeled * PHY_RXSTART is not supported * The current implementation assumes that secondary channels are always higher than primary channels * Cases where RTS/CTS and ACK are transmitted using HT/VHT/HE formats are not supported @@ -297,9 +296,9 @@ In the standard, there is also what is called the "minimum modulation and coding rate sensitivity" in section 18.3.10.6 CCA requirements. This is analogous to the RxSensitivity attribute in ``YansWifiPhy``. CCA busy state is not raised in this model when this threshold is exceeded -but instead RX state is immediately reached, since it is assumed that PLCP -sync always succeeds in this model. Even if the PLCP header reception fails, the -channel state is still held in RX until YansWifiPhy::EndReceive(). +but instead RX state is immediately reachedif PHY preamble detection is successful. +Even if the PHY header reception fails, the channel state is still held +in RX until YansWifiPhy::EndReceive(). In ns-3, the values of these attributes are -101 dBm for RxSensitivity and -62 dBm for CcaEdThreshold. @@ -311,10 +310,15 @@ calculated from the transmission power and adjusted based on the Tx gain of the transmitter, Rx gain of the receiver, and any path loss propagation model in effect. -The packet reception occurs in two stages. First, an event is scheduled -for when the PLCP header has been received. PLCP header is often transmitted +The packet reception occurs in three stages. First, an event is scheduled +for when PHY preamble has been detected. This decides whether the preamble +can be detected, by calling a preamble detection model. In case there is no +preamble detection model attached to the PHY, it assumes preamble is always detected. +Currently, there is only a simple threshold-based preamble detection model in ns-3, +called ``ThresholdPreambleDetectionModel``. If PHY preamble has been successfully detected, +it schedules a second event for when PHY header has been received. PHY header is often transmitted at a lower modulation rate than is the payload. The portion of the packet -corresponding to the PLCP header is evaluated for probability of error +corresponding to the PHY header is evaluated for probability of error based on the observed SNR. The InterferenceHelper object returns a value for "probability of error (PER)" for this header based on the SNR that has been tracked by the InterferenceHelper. The ``YansWifiPhy`` then draws diff --git a/src/wifi/model/interference-helper.cc b/src/wifi/model/interference-helper.cc index f9346e669..5bba2bf91 100644 --- a/src/wifi/model/interference-helper.cc +++ b/src/wifi/model/interference-helper.cc @@ -25,6 +25,7 @@ #include "interference-helper.h" #include "wifi-phy.h" #include "error-rate-model.h" +#include "wifi-utils.h" namespace ns3 { @@ -229,26 +230,36 @@ InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint1 double noiseFloor = m_noiseFigure * Nt; double noise = noiseFloor + noiseInterference; double snr = signal / noise; //linear scale - NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr(linear)=" << snr); + NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr=" << RatioToDb(snr) << "dB"); return snr; } double InterferenceHelper::CalculateNoiseInterferenceW (Ptr event, NiChanges *ni) const { - double noiseInterference = m_firstPower; + double noiseInterferenceW = m_firstPower; auto it = m_niChanges.find (event->GetStartTime ()); - for (; it != m_niChanges.end () && it->second.GetEvent () != event; ++it) + for (; it != m_niChanges.end (); ++it) { - noiseInterference = it->second.GetPower (); + if (it->second.GetEvent () == event) + { + continue; + } + if (it->first > Simulator::Now ()) + { + break; + } + noiseInterferenceW = it->second.GetPower () - event->GetRxPowerW (); } + it = m_niChanges.find (event->GetStartTime ()); + for (; it != m_niChanges.end () && it->second.GetEvent () != event; ++it); ni->emplace (event->GetStartTime (), NiChange (0, event)); while (++it != m_niChanges.end () && it->second.GetEvent () != event) { ni->insert (*it); } ni->emplace (event->GetEndTime (), NiChange (0, event)); - return noiseInterference; + return noiseInterferenceW; } double diff --git a/src/wifi/model/preamble-detection-model.cc b/src/wifi/model/preamble-detection-model.cc new file mode 100644 index 000000000..d956807ae --- /dev/null +++ b/src/wifi/model/preamble-detection-model.cc @@ -0,0 +1,36 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#include "preamble-detection-model.h" + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (PreambleDetectionModel); + +TypeId PreambleDetectionModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::PreambleDetectionModel") + .SetParent () + .SetGroupName ("Wifi") + ; + return tid; +} + +} //namespace ns3 diff --git a/src/wifi/model/preamble-detection-model.h b/src/wifi/model/preamble-detection-model.h new file mode 100644 index 000000000..195f01023 --- /dev/null +++ b/src/wifi/model/preamble-detection-model.h @@ -0,0 +1,58 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#ifndef PREAMBLE_DETECTION_MODEL_H +#define PREAMBLE_DETECTION_MODEL_H + +#include "ns3/object.h" + +namespace ns3 { + +/** + * \ingroup wifi + * \brief the interface for Wifi's preamble detection models + * + */ +class PreambleDetectionModel : public Object +{ +public: + /** + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId (void); + + /** + * A pure virtual method that must be implemented in the subclass. + * This method returns whether the preamble detection was successful. + * + * \param snr the SNR of the received signal. + * \param channelWidth the channel width of the received signal in MHz. + * + * \return true if the preamble has been detected, + * false otherwise + */ + virtual bool IsPreambleDetected (double snr, double channelWidth) const = 0; +}; + +} //namespace ns3 + +#endif /* PREAMBLE_DETECTION_MODEL_H */ + diff --git a/src/wifi/model/spectrum-wifi-phy.cc b/src/wifi/model/spectrum-wifi-phy.cc index 7fc52a25a..5abc5897b 100644 --- a/src/wifi/model/spectrum-wifi-phy.cc +++ b/src/wifi/model/spectrum-wifi-phy.cc @@ -240,7 +240,7 @@ SpectrumWifiPhy::StartRx (Ptr rxParams) NS_LOG_INFO ("Received Wi-Fi signal"); Ptr packet = wifiRxParams->packet->Copy (); - StartReceivePreambleAndHeader (packet, rxPowerW, rxDuration); + StartReceivePreamble (packet, rxPowerW, rxDuration); } Ptr diff --git a/src/wifi/model/threshold-preamble-detection-model.cc b/src/wifi/model/threshold-preamble-detection-model.cc new file mode 100644 index 000000000..8772d404f --- /dev/null +++ b/src/wifi/model/threshold-preamble-detection-model.cc @@ -0,0 +1,65 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#include "ns3/log.h" +#include "ns3/double.h" +#include "threshold-preamble-detection-model.h" +#include "wifi-utils.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("ThresholdPreambleDetectionModel"); + +NS_OBJECT_ENSURE_REGISTERED (ThresholdPreambleDetectionModel); + +TypeId +ThresholdPreambleDetectionModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::ThresholdPreambleDetectionModel") + .SetParent () + .SetGroupName ("Wifi") + .AddConstructor () + .AddAttribute ("Threshold", + "Preamble is successfully detection if the SNR is at or above this value (expressed in dB).", + DoubleValue (2), + MakeDoubleAccessor (&ThresholdPreambleDetectionModel::m_threshold), + MakeDoubleChecker ()) + ; + return tid; +} + +ThresholdPreambleDetectionModel::ThresholdPreambleDetectionModel () +{ + NS_LOG_FUNCTION (this); +} + +ThresholdPreambleDetectionModel::~ThresholdPreambleDetectionModel () +{ + NS_LOG_FUNCTION (this); +} + +bool +ThresholdPreambleDetectionModel::IsPreambleDetected (double snr, double channelWidth) const +{ + NS_LOG_FUNCTION (this); + return (RatioToDb (snr) >= m_threshold); +} + +} //namespace ns3 diff --git a/src/wifi/model/threshold-preamble-detection-model.h b/src/wifi/model/threshold-preamble-detection-model.h new file mode 100644 index 000000000..dbc56fc96 --- /dev/null +++ b/src/wifi/model/threshold-preamble-detection-model.h @@ -0,0 +1,63 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#ifndef THRESHOLD_PREAMBLE_DETECTION_MODEL_H +#define THRESHOLD_PREAMBLE_DETECTION_MODEL_H + +#include "preamble-detection-model.h" + +namespace ns3 { +/** + * \ingroup wifi + * + * A threshold-based model for detecting PHY preamble. + * This model assumes that a preamble is successfully detected if SNR is at or above a given threshold. By default, this threshold is set to 2 dB. + */ +class ThresholdPreambleDetectionModel : public PreambleDetectionModel +{ +public: + /** + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId (void); + + ThresholdPreambleDetectionModel (); + ~ThresholdPreambleDetectionModel (); + + /** + * This method returns whether the preamble detection was successful. + * + * \param snr the SNR ratio (not dB) of the received signal. + * \param channelWidth the channel width of the received signal in MHz. + * + * \return true if the preamble has been detected, + * false otherwise + */ + bool IsPreambleDetected (double snr, double channelWidth) const; + + +private: + double m_threshold; ///< SNR threshold in dB used to decide whether a preamble is successfully received +}; + +} //namespace ns3 + +#endif /* THRESHOLD_PREAMBLE_DETECTION_MODEL_H */ diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index f37b620c3..673dae01f 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -30,6 +30,7 @@ #include "ampdu-tag.h" #include "wifi-utils.h" #include "frame-capture-model.h" +#include "preamble-detection-model.h" #include "wifi-radio-energy-model.h" #include "error-rate-model.h" #include "wifi-net-device.h" @@ -308,6 +309,11 @@ WifiPhy::GetTypeId (void) PointerValue (), MakePointerAccessor (&WifiPhy::m_frameCaptureModel), MakePointerChecker ()) + .AddAttribute ("PreambleDetectionModel", + "Ptr to an object that implements the preamble detection model", + PointerValue (), + MakePointerAccessor (&WifiPhy::m_preambleDetectionModel), + MakePointerChecker ()) .AddAttribute ("PostReceptionErrorModel", "An optional packet error model can be added to the receive " "packet process after any propagation-based (SNR-based) error " @@ -372,6 +378,7 @@ WifiPhy::WifiPhy () m_rxMpduReferenceNumber (0xffffffff), m_endRxEvent (), m_endPlcpRxEvent (), + m_endPreambleDetectionEvent (), m_standard (WIFI_PHY_STANDARD_UNSPECIFIED), m_isConstructed (false), m_channelCenterFrequency (0), @@ -401,6 +408,9 @@ void WifiPhy::DoDispose (void) { NS_LOG_FUNCTION (this); + m_endRxEvent.Cancel (); + m_endPlcpRxEvent.Cancel (); + m_endPreambleDetectionEvent.Cancel (); m_device = 0; m_mobility = 0; m_state = 0; @@ -762,6 +772,12 @@ WifiPhy::SetFrameCaptureModel (const Ptr model) m_frameCaptureModel = model; } +void +WifiPhy::SetPreambleDetectionModel (const Ptr model) +{ + m_preambleDetectionModel = model; +} + void WifiPhy::SetWifiRadioEnergyModel (const Ptr wifiRadioEnergyModel) { @@ -1506,6 +1522,7 @@ WifiPhy::DoChannelSwitch (uint8_t nch) NS_LOG_DEBUG ("drop packet because of channel switching while reception"); m_endPlcpRxEvent.Cancel (); m_endRxEvent.Cancel (); + m_endPreambleDetectionEvent.Cancel (); goto switchChannel; break; case WifiPhyState::TX: @@ -1514,6 +1531,11 @@ WifiPhy::DoChannelSwitch (uint8_t nch) break; case WifiPhyState::CCA_BUSY: case WifiPhyState::IDLE: + if (m_endPreambleDetectionEvent.IsRunning ()) + { + m_endPreambleDetectionEvent.Cancel (); + m_endRxEvent.Cancel (); + } goto switchChannel; break; case WifiPhyState::SLEEP: @@ -1558,6 +1580,7 @@ WifiPhy::DoFrequencySwitch (uint16_t frequency) NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception"); m_endPlcpRxEvent.Cancel (); m_endRxEvent.Cancel (); + m_endPreambleDetectionEvent.Cancel (); goto switchFrequency; break; case WifiPhyState::TX: @@ -1566,6 +1589,11 @@ WifiPhy::DoFrequencySwitch (uint16_t frequency) break; case WifiPhyState::CCA_BUSY: case WifiPhyState::IDLE: + if (m_endPreambleDetectionEvent.IsRunning ()) + { + m_endPreambleDetectionEvent.Cancel (); + m_endRxEvent.Cancel (); + } goto switchFrequency; break; case WifiPhyState::SLEEP: @@ -1629,22 +1657,10 @@ void WifiPhy::SetOffMode (void) { NS_LOG_FUNCTION (this); - switch (m_state->GetState ()) - { - case WifiPhyState::RX: - m_endPlcpRxEvent.Cancel (); - m_endRxEvent.Cancel (); - case WifiPhyState::TX: - case WifiPhyState::SWITCHING: - case WifiPhyState::CCA_BUSY: - case WifiPhyState::IDLE: - case WifiPhyState::SLEEP: - m_state->SwitchToOff (); - break; - default: - NS_ASSERT (false); - break; - } + m_endPlcpRxEvent.Cancel (); + m_endRxEvent.Cancel (); + m_endPreambleDetectionEvent.Cancel (); + m_state->SwitchToOff (); } void @@ -1726,6 +1742,12 @@ WifiPhy::GetHePlcpHeaderMode () return WifiPhy::GetHeMcs0 (); } +Time +WifiPhy::GetPreambleDetectionDuration (void) +{ + return MicroSeconds (4); +} + Time WifiPhy::GetPlcpTrainingSymbolDuration (WifiTxVector txVector) { @@ -2389,12 +2411,23 @@ WifiPhy::SendPacket (Ptr packet, WifiTxVector txVector, MpduType m Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, GetFrequency (), mpdutype, 1); NS_ASSERT (txDuration.IsStrictlyPositive ()); - if (m_state->IsStateRx ()) + if (m_endPreambleDetectionEvent.IsRunning ()) + { + m_endPreambleDetectionEvent.Cancel (); + } + if (m_endPlcpRxEvent.IsRunning ()) { m_endPlcpRxEvent.Cancel (); + } + if (m_endRxEvent.IsRunning ()) + { m_endRxEvent.Cancel (); + } + if (m_state->IsStateRx ()) + { m_interference.NotifyRxEnd (); } + NotifyTxBegin (packet); if ((mpdutype == MPDU_IN_AGGREGATE) && (txVector.GetPreambleType () != WIFI_PREAMBLE_NONE)) { @@ -2427,7 +2460,39 @@ WifiPhy::SendPacket (Ptr packet, WifiTxVector txVector, MpduType m } void -WifiPhy::StartReceivePreambleAndHeader (Ptr packet, double rxPowerW, Time rxDuration) +WifiPhy::StartReceiveHeader (Ptr packet, WifiTxVector txVector, MpduType mpdutype, Ptr event, Time rxDuration) +{ + NS_LOG_FUNCTION (this << packet << txVector.GetMode () << txVector.GetPreambleType () << +mpdutype); + NS_ASSERT (!IsStateRx ()); + NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); + + InterferenceHelper::SnrPer snrPer = m_interference.CalculatePlcpHeaderSnrPer (event); + double snr = snrPer.snr; + NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per); + + if (!m_preambleDetectionModel || (m_preambleDetectionModel->IsPreambleDetected (snr, m_channelWidth))) + { + m_state->SwitchToRx (rxDuration); + NotifyRxBegin (packet); + + Time remainingPreambleHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector) - GetPreambleDetectionDuration (); + m_endPlcpRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePacket, this, + packet, txVector, mpdutype, event); + + NS_ASSERT (m_endRxEvent.IsExpired ()); + m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this, + packet, txVector.GetPreambleType (), mpdutype, event); + } + else + { + NS_LOG_DEBUG ("Packet reception could not be started because PHY preamble detection failed"); + m_plcpSuccess = false; + m_interference.NotifyRxEnd (); + } +} + +void +WifiPhy::StartReceivePreamble (Ptr packet, double rxPowerW, Time rxDuration) { WifiPhyTag tag; bool found = packet->RemovePacketTag (tag); @@ -2456,8 +2521,7 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr packet, double rxPowerW, Tim if (tag.GetFrameComplete () == 0) { - NS_LOG_DEBUG ("drop packet because of incomplete frame"); - NotifyRxDrop (packet); + NS_LOG_DEBUG ("Packet reception stopped because transmitter has been switched off"); m_plcpSuccess = false; return; } @@ -2471,8 +2535,7 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr packet, double rxPowerW, Tim Time endRx = Simulator::Now () + rxDuration; if (txVector.GetNss () > GetMaxSupportedRxSpatialStreams ()) { - NS_LOG_DEBUG ("drop packet because not enough RX antennas"); - NotifyRxDrop (packet); + NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas"); m_plcpSuccess = false; if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) { @@ -2585,8 +2648,6 @@ WifiPhy::StartReceivePacket (Ptr packet, InterferenceHelper::SnrPer snrPer; snrPer = m_interference.CalculatePlcpHeaderSnrPer (event); - NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per); - if (m_random->GetValue () > snrPer.per) //plcp reception succeeded { if (IsModeSupported (txMode) || IsMcsSupported (txMode)) @@ -2603,7 +2664,7 @@ WifiPhy::StartReceivePacket (Ptr packet, } else //plcp reception failed { - NS_LOG_DEBUG ("drop packet because plcp preamble/header reception failed"); + NS_LOG_DEBUG ("drop packet because PHY header reception failed"); NotifyRxDrop (packet); m_plcpSuccess = false; } @@ -3679,6 +3740,10 @@ void WifiPhy::AbortCurrentReception () { NS_LOG_FUNCTION (this); + if (m_endPreambleDetectionEvent.IsRunning ()) + { + m_endPreambleDetectionEvent.Cancel (); + } if (m_endPlcpRxEvent.IsRunning ()) { m_endPlcpRxEvent.Cancel (); @@ -3741,22 +3806,31 @@ WifiPhy::StartRx (Ptr packet, WifiTxVector txVector, MpduType mpdutype, NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)"); m_currentEvent = event; - m_state->SwitchToRx (rxDuration); - NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); - NotifyRxBegin (packet); - m_interference.NotifyRxStart (); - - if (preamble != WIFI_PREAMBLE_NONE) + m_interference.NotifyRxStart (); //We need to notify it now so that it starts recording events + if (preamble == WIFI_PREAMBLE_NONE) { - NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); - Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector); - m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this, - packet, txVector, mpdutype, event); - } + m_state->SwitchToRx (rxDuration); + NotifyRxBegin (packet); + m_interference.NotifyRxStart (); - NS_ASSERT (m_endRxEvent.IsExpired ()); - m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this, - packet, preamble, mpdutype, event); + NS_ASSERT (m_endRxEvent.IsExpired ()); + m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this, + packet, txVector.GetPreambleType (), mpdutype, event); + } + else + { + if (!m_endPreambleDetectionEvent.IsRunning ()) + { + Time startOfPreambleDuration = GetPreambleDetectionDuration (); + Time remainingRxDuration = rxDuration - startOfPreambleDuration; + m_endPreambleDetectionEvent = Simulator::Schedule (startOfPreambleDuration, &WifiPhy::StartReceiveHeader, this, + packet, txVector, mpdutype, event, remainingRxDuration); + } + else + { + NS_LOG_DEBUG ("Ignore packet because RX is already decoding preamble"); + } + } } int64_t diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index 3131e38fd..ffaa194db 100644 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -41,6 +41,7 @@ class NetDevice; class MobilityModel; class WifiPhyStateHelper; class FrameCaptureModel; +class PreambleDetectionModel; class WifiRadioEnergyModel; class UniformRandomVariable; @@ -114,15 +115,29 @@ public: void SetCapabilitiesChangedCallback (Callback callback); /** - * Starting receiving the plcp of a packet (i.e. the first bit of the preamble has arrived). + * Starting receiving the PHY preamble of a packet (i.e. the first bit of the preamble has arrived). * * \param packet the arriving packet * \param rxPowerW the receive power in W * \param rxDuration the duration needed for the reception of the packet */ - void StartReceivePreambleAndHeader (Ptr packet, - double rxPowerW, - Time rxDuration); + void StartReceivePreamble (Ptr packet, + double rxPowerW, + Time rxDuration); + + /** + * Starting receiving the PHY header of a packet (i.e. after the end of receiving the preamble). + * + * \param packet the arriving packet + * \param txVector the TXVECTOR of the arriving packet + * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType. + * \param event the corresponding event of the first time the packet arrives + */ + void StartReceiveHeader (Ptr packet, + WifiTxVector txVector, + MpduType mpdutype, + Ptr event, + Time rxDuration); /** * Starting receiving the payload of a packet (i.e. the first bit of the packet has arrived). @@ -252,6 +267,12 @@ public: */ static Time CalculatePlcpPreambleAndHeaderDuration (WifiTxVector txVector); + /** + * + * \return the preamble detection duration, which is the time correletion needs to detect the start of an incoming frame. + */ + Time GetPreambleDetectionDuration (void); + /** * \param txVector the transmission parameters used for this packet * @@ -1446,6 +1467,12 @@ public: * \param frameCaptureModel the frame capture model */ void SetFrameCaptureModel (const Ptr frameCaptureModel); + /** + * Sets the preamble detection model. + * + * \param preambleDetectionModel the preamble detection model + */ + void SetPreambleDetectionModel (const Ptr preambleDetectionModel); /** * Sets the wifi radio energy model. * @@ -1524,8 +1551,9 @@ protected: uint32_t m_txMpduReferenceNumber; //!< A-MPDU reference number to identify all transmitted subframes belonging to the same received A-MPDU uint32_t m_rxMpduReferenceNumber; //!< A-MPDU reference number to identify all received subframes belonging to the same received A-MPDU - EventId m_endRxEvent; //!< the end reeive event - EventId m_endPlcpRxEvent; //!< the end PLCP receive event + EventId m_endRxEvent; //!< the end of receive event + EventId m_endPlcpRxEvent; //!< the end of PLCP receive event + EventId m_endPreambleDetectionEvent; //!< the end of preamble detection event private: /** @@ -1807,6 +1835,7 @@ private: Ptr m_currentEvent; //!< Hold the current event Ptr m_frameCaptureModel; //!< Frame capture model + Ptr m_preambleDetectionModel; //!< Preamble detection model Ptr m_wifiRadioEnergyModel; //!< Wifi radio energy model Ptr m_postReceptionErrorModel; //!< Error model for receive packet events diff --git a/src/wifi/model/yans-wifi-channel.cc b/src/wifi/model/yans-wifi-channel.cc index c967c22ae..016652868 100644 --- a/src/wifi/model/yans-wifi-channel.cc +++ b/src/wifi/model/yans-wifi-channel.cc @@ -132,7 +132,7 @@ YansWifiChannel::Receive (Ptr phy, Ptr packet, double rxPow NS_LOG_INFO ("Received signal too weak to process: " << rxPowerDbm << " dBm"); return; } - phy->StartReceivePreambleAndHeader (packet, DbmToW (rxPowerDbm + phy->GetRxGain ()), duration); + phy->StartReceivePreamble (packet, DbmToW (rxPowerDbm + phy->GetRxGain ()), duration); } std::size_t diff --git a/src/wifi/test/preamble-detection-test.cc b/src/wifi/test/preamble-detection-test.cc new file mode 100644 index 000000000..9210df85f --- /dev/null +++ b/src/wifi/test/preamble-detection-test.cc @@ -0,0 +1,254 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#include "ns3/log.h" +#include "ns3/test.h" +#include "ns3/pointer.h" +#include "ns3/spectrum-wifi-helper.h" +#include "ns3/wifi-spectrum-value-helper.h" +#include "ns3/spectrum-wifi-phy.h" +#include "ns3/nist-error-rate-model.h" +#include "ns3/wifi-mac-header.h" +#include "ns3/wifi-mac-trailer.h" +#include "ns3/wifi-phy-tag.h" +#include "ns3/wifi-spectrum-signal-parameters.h" +#include "ns3/wifi-utils.h" +#include "ns3/threshold-preamble-detection-model.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("TestThresholdPreambleDetectionWithoutFrameCapture"); + +static const uint8_t CHANNEL_NUMBER = 36; +static const uint32_t FREQUENCY = 5180; // MHz +static const uint16_t CHANNEL_WIDTH = 20; // MHz +static const uint16_t GUARD_WIDTH = CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask) + +/** + * \ingroup wifi-test + * \ingroup tests + * + * \brief Wifi Preamble Detection Test + */ +class TestThresholdPreambleDetectionWithoutFrameCapture : public TestCase +{ +public: + TestThresholdPreambleDetectionWithoutFrameCapture (); + virtual ~TestThresholdPreambleDetectionWithoutFrameCapture (); + +protected: + virtual void DoSetup (void); + Ptr m_phy; ///< Phy + /** + * Send packet function + * \param txPowerDbm the transmit power in dBm + */ + void SendPacket (double txPowerDbm); + /** + * Spectrum wifi receive success function + * \param p the packet + * \param snr the SNR + * \param txVector the transmit vector + */ + void SpectrumWifiPhyRxSuccess (Ptr p, double snr, WifiTxVector txVector); + /** + * Spectrum wifi receive failure function + */ + void SpectrumWifiPhyRxFailure (void); + uint32_t m_countRxSuccess; ///< count RX success + uint32_t m_countRxFailure; ///< count RX failure + +private: + virtual void DoRun (void); + + /** + * Check the PHY state + * \param expectedState the expected PHY state + */ + void CheckPhyState (WifiPhyState expectedState); + /** + * Check the number of received packets + * \param expectedSuccessCount the number of successfully received packets + * \param expectedFailureCount the number of unsuccessfully received packets + */ + void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount); +}; + +TestThresholdPreambleDetectionWithoutFrameCapture::TestThresholdPreambleDetectionWithoutFrameCapture () + : TestCase ("Threshold preamble detection model test when no frame capture model is applied"), + m_countRxSuccess (0), + m_countRxFailure (0) +{ +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket (double txPowerDbm) +{ + WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs11 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false); + MpduType mpdutype = NORMAL_MPDU; + + Ptr pkt = Create (1000); + WifiMacHeader hdr; + WifiMacTrailer trailer; + + hdr.SetType (WIFI_MAC_QOSDATA); + hdr.SetQosTid (0); + uint32_t size = pkt->GetSize () + hdr.GetSize () + trailer.GetSerializedSize (); + Time txDuration = m_phy->CalculateTxDuration (size, txVector, m_phy->GetFrequency (), mpdutype, 0); + hdr.SetDuration (txDuration); + + pkt->AddHeader (hdr); + pkt->AddTrailer (trailer); + WifiPhyTag tag (txVector, mpdutype, 1); + pkt->AddPacketTag (tag); + Ptr txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (txPowerDbm), GUARD_WIDTH); + Ptr txParams = Create (); + txParams->psd = txPowerSpectrum; + txParams->txPhy = 0; + txParams->duration = txDuration; + txParams->packet = pkt; + + m_phy->StartRx (txParams); +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState (WifiPhyState expectedState) +{ + WifiPhyState currentState; + PointerValue ptr; + m_phy->GetAttribute ("State", ptr); + Ptr state = DynamicCast (ptr.Get ()); + currentState = state->GetState (); + NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ()); +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount) +{ + NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets"); + NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets"); +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::SpectrumWifiPhyRxSuccess (Ptr p, double snr, WifiTxVector txVector) +{ + NS_LOG_FUNCTION (this << p << snr << txVector); + m_countRxSuccess++; +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::SpectrumWifiPhyRxFailure (void) +{ + NS_LOG_FUNCTION (this); + m_countRxFailure++; +} + +TestThresholdPreambleDetectionWithoutFrameCapture::~TestThresholdPreambleDetectionWithoutFrameCapture () +{ +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::DoSetup (void) +{ + m_phy = CreateObject (); + m_phy->ConfigureStandard (WIFI_PHY_STANDARD_80211ax_5GHZ); + Ptr error = CreateObject (); + m_phy->SetErrorRateModel (error); + m_phy->SetChannelNumber (CHANNEL_NUMBER); + m_phy->SetFrequency (FREQUENCY); + m_phy->SetReceiveOkCallback (MakeCallback (&TestThresholdPreambleDetectionWithoutFrameCapture::SpectrumWifiPhyRxSuccess, this)); + m_phy->SetReceiveErrorCallback (MakeCallback (&TestThresholdPreambleDetectionWithoutFrameCapture::SpectrumWifiPhyRxFailure, this)); + + Ptr preambleDetectionModel = CreateObject (); + m_phy->SetPreambleDetectionModel (preambleDetectionModel); +} + +// Test that the expected number of packet receptions occur. +void +TestThresholdPreambleDetectionWithoutFrameCapture::DoRun (void) +{ + double txPowerDbm = -30; + + //CASE 1: send one packet and check PHY state: packet reception should succeed + + Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + // At 4us, STA PHY STATE should be IDLE + Simulator::Schedule (Seconds (1.0) + MicroSeconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + // At 5us, STA PHY STATE should be RX + Simulator::Schedule (Seconds (1.0) + MicroSeconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::RX); + // Packet should have been successfully received + Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0); + + //CASE 2: send two packets with same power within the 4us window and check PHY state: PHY preamble detection should fail + + Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + Simulator::Schedule (Seconds (2.0) + MicroSeconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + Simulator::Schedule (Seconds (2.0) + MicroSeconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure + Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0); + + //CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should succeed and packet reception should fail + + Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm - 3); + Simulator::Schedule (Seconds (3.0) + MicroSeconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + Simulator::Schedule (Seconds (3.0) + MicroSeconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::RX); + // In this case, the first packet should be marked as a failure + Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1); + + //CASE 4: send two packets with second one 3 dB higher within the 4us window and check PHY state: PHY preamble detection should fail and no packets should enter the reception stage + Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm + 3); + Simulator::Schedule (Seconds (4.0) + MicroSeconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + Simulator::Schedule (Seconds (4.0) + MicroSeconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1); + + //CASE 5: idem but send the second packet after the 4us window: PHY preamble detection should succeed and packet reception should fail + + Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + Simulator::Schedule (Seconds (5.0) + MicroSeconds (6.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm + 3); + Simulator::Schedule (Seconds (5.0) + MicroSeconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + Simulator::Schedule (Seconds (5.0) + MicroSeconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::RX); + Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 2); + + Simulator::Run (); + Simulator::Destroy (); +} + +/** + * \ingroup wifi-test + * \ingroup tests + * + * \brief Preamble Detection Test Suite + */ +class PreambleDetectionTestSuite : public TestSuite +{ +public: + PreambleDetectionTestSuite (); +}; + +PreambleDetectionTestSuite::PreambleDetectionTestSuite () + : TestSuite ("wifi-preamble-detection", UNIT) +{ + AddTestCase (new TestThresholdPreambleDetectionWithoutFrameCapture, TestCase::QUICK); +} + +static PreambleDetectionTestSuite preambleDetectionTestSuite; ///< the test suite diff --git a/src/wifi/test/wifi-test.cc b/src/wifi/test/wifi-test.cc index 7b5428997..6f633bb75 100644 --- a/src/wifi/test/wifi-test.cc +++ b/src/wifi/test/wifi-test.cc @@ -1025,7 +1025,6 @@ SetChannelFrequencyTest::DoRun () } Simulator::Destroy (); - } //----------------------------------------------------------------------------- @@ -1656,6 +1655,9 @@ void StaWifiMacScanningTestCase::DoRun (void) { { + RngSeedManager::SetSeed (1); + RngSeedManager::SetRun (1); + NodeContainer nodes = Setup (false, false); Ptr nearestAp = nodes.Get (2); Mac48Address nearestApAddr = DynamicCast (nearestAp->GetDevice (0))->GetMac ()->GetAddress (); @@ -1670,6 +1672,9 @@ StaWifiMacScanningTestCase::DoRun (void) } m_associatedApBssid = Mac48Address (); { + RngSeedManager::SetSeed (1); + RngSeedManager::SetRun (1); + NodeContainer nodes = Setup (true, true); Ptr nearestAp = nodes.Get (2); Mac48Address nearestApAddr = DynamicCast (nearestAp->GetDevice (0))->GetMac ()->GetAddress (); @@ -1682,6 +1687,9 @@ StaWifiMacScanningTestCase::DoRun (void) } m_associatedApBssid = Mac48Address (); { + RngSeedManager::SetSeed (1); + RngSeedManager::SetRun (1); + NodeContainer nodes = Setup (true, false); Ptr nearestAp = nodes.Get (2); Mac48Address secondNearestApAddr = DynamicCast (nodes.Get (1)->GetDevice (0))->GetMac ()->GetAddress (); diff --git a/src/wifi/wscript b/src/wifi/wscript index d1b3e3767..4da5c7bdb 100644 --- a/src/wifi/wscript +++ b/src/wifi/wscript @@ -85,6 +85,8 @@ def build(bld): 'model/he-capabilities.cc', 'model/frame-capture-model.cc', 'model/simple-frame-capture-model.cc', + 'model/preamble-detection-model.cc', + 'model/threshold-preamble-detection-model.cc', 'model/he-operation.cc', 'model/he-configuration.cc', 'model/extended-capabilities.cc', @@ -112,6 +114,7 @@ def build(bld): 'test/wifi-error-rate-models-test.cc', 'test/wifi-transmit-mask-test.cc', 'test/wifi-phy-thresholds-test.cc', + 'test/preamble-detection-test.cc', ] headers = bld(features='ns3header') @@ -200,6 +203,8 @@ def build(bld): 'model/he-capabilities.h', 'model/frame-capture-model.h', 'model/simple-frame-capture-model.h', + 'model/preamble-detection-model.h', + 'model/threshold-preamble-detection-model.h', 'model/qos-blocked-destinations.h', 'model/he-operation.h', 'model/he-configuration.h',