test_ap_ht.py 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370
  1. # Test cases for HT operations with hostapd
  2. # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
  3. #
  4. # This software may be distributed under the terms of the BSD license.
  5. # See README for more details.
  6. from remotehost import remote_compatible
  7. import time
  8. import logging
  9. logger = logging.getLogger()
  10. import struct
  11. import hostapd
  12. from utils import HwsimSkip, alloc_fail, parse_ie
  13. import hwsim_utils
  14. from test_ap_csa import csa_supported
  15. def clear_scan_cache(apdev):
  16. ifname = apdev['ifname']
  17. hostapd.cmd_execute(apdev, ['ifconfig', ifname, 'up'])
  18. hostapd.cmd_execute(apdev, ['iw', ifname, 'scan', 'trigger', 'freq', '2412',
  19. 'flush'])
  20. time.sleep(0.1)
  21. hostapd.cmd_execute(apdev, ['ifconfig', ifname, 'down'])
  22. def set_world_reg(apdev0=None, apdev1=None, dev0=None):
  23. if apdev0:
  24. hostapd.cmd_execute(apdev0, ['iw', 'reg', 'set', '00'])
  25. if apdev1:
  26. hostapd.cmd_execute(apdev1, ['iw', 'reg', 'set', '00'])
  27. if dev0:
  28. dev0.cmd_execute(['iw', 'reg', 'set', '00'])
  29. def test_ap_ht40_scan(dev, apdev):
  30. """HT40 co-ex scan"""
  31. clear_scan_cache(apdev[0])
  32. params = { "ssid": "test-ht40",
  33. "channel": "5",
  34. "ht_capab": "[HT40-]"}
  35. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  36. state = hapd.get_status_field("state")
  37. if state != "HT_SCAN":
  38. time.sleep(0.1)
  39. state = hapd.get_status_field("state")
  40. if state != "HT_SCAN":
  41. raise Exception("Unexpected interface state - expected HT_SCAN")
  42. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  43. if not ev:
  44. raise Exception("AP setup timed out")
  45. state = hapd.get_status_field("state")
  46. if state != "ENABLED":
  47. raise Exception("Unexpected interface state - expected ENABLED")
  48. freq = hapd.get_status_field("freq")
  49. if freq != "2432":
  50. raise Exception("Unexpected frequency")
  51. pri = hapd.get_status_field("channel")
  52. if pri != "5":
  53. raise Exception("Unexpected primary channel")
  54. sec = hapd.get_status_field("secondary_channel")
  55. if sec != "-1":
  56. raise Exception("Unexpected secondary channel")
  57. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  58. @remote_compatible
  59. def test_ap_ht40_scan_conflict(dev, apdev):
  60. """HT40 co-ex scan conflict"""
  61. clear_scan_cache(apdev[0])
  62. params = { "ssid": "test-ht40",
  63. "channel": "6",
  64. "ht_capab": "[HT40+]"}
  65. hostapd.add_ap(apdev[1], params)
  66. params = { "ssid": "test-ht40",
  67. "channel": "5",
  68. "ht_capab": "[HT40-]"}
  69. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  70. state = hapd.get_status_field("state")
  71. if state != "HT_SCAN":
  72. time.sleep(0.1)
  73. state = hapd.get_status_field("state")
  74. if state != "HT_SCAN":
  75. raise Exception("Unexpected interface state - expected HT_SCAN")
  76. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  77. if not ev:
  78. raise Exception("AP setup timed out")
  79. state = hapd.get_status_field("state")
  80. if state != "ENABLED":
  81. raise Exception("Unexpected interface state - expected ENABLED")
  82. freq = hapd.get_status_field("freq")
  83. if freq != "2432":
  84. raise Exception("Unexpected frequency")
  85. pri = hapd.get_status_field("channel")
  86. if pri != "5":
  87. raise Exception("Unexpected primary channel")
  88. sec = hapd.get_status_field("secondary_channel")
  89. if sec != "0":
  90. raise Exception("Unexpected secondary channel: " + sec)
  91. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  92. @remote_compatible
  93. def test_ap_ht40_scan_conflict2(dev, apdev):
  94. """HT40 co-ex scan conflict (HT40-)"""
  95. clear_scan_cache(apdev[0])
  96. params = { "ssid": "test-ht40",
  97. "channel": "11",
  98. "ht_capab": "[HT40-]"}
  99. hostapd.add_ap(apdev[1], params)
  100. params = { "ssid": "test-ht40",
  101. "channel": "1",
  102. "ht_capab": "[HT40+]"}
  103. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  104. state = hapd.get_status_field("state")
  105. if state != "HT_SCAN":
  106. time.sleep(0.1)
  107. state = hapd.get_status_field("state")
  108. if state != "HT_SCAN":
  109. raise Exception("Unexpected interface state - expected HT_SCAN")
  110. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  111. if not ev:
  112. raise Exception("AP setup timed out")
  113. state = hapd.get_status_field("state")
  114. if state != "ENABLED":
  115. raise Exception("Unexpected interface state - expected ENABLED")
  116. freq = hapd.get_status_field("freq")
  117. if freq != "2412":
  118. raise Exception("Unexpected frequency")
  119. pri = hapd.get_status_field("channel")
  120. if pri != "1":
  121. raise Exception("Unexpected primary channel")
  122. sec = hapd.get_status_field("secondary_channel")
  123. if sec != "0":
  124. raise Exception("Unexpected secondary channel: " + sec)
  125. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  126. def test_ap_ht40_scan_not_affected(dev, apdev):
  127. """HT40 co-ex scan and other BSS not affected"""
  128. clear_scan_cache(apdev[0])
  129. params = { "ssid": "test-ht20",
  130. "channel": "11" }
  131. hostapd.add_ap(apdev[1], params)
  132. hostapd.cmd_execute(apdev[0], ['ifconfig', apdev[0]['ifname'], 'up'])
  133. hostapd.cmd_execute(apdev[0], ['iw', apdev[0]['ifname'], 'scan', 'trigger',
  134. 'freq', '2462'])
  135. time.sleep(0.5)
  136. hostapd.cmd_execute(apdev[0], ['iw', apdev[0]['ifname'], 'scan', 'dump'])
  137. time.sleep(0.1)
  138. hostapd.cmd_execute(apdev[0], ['ifconfig', apdev[0]['ifname'], 'down'])
  139. params = { "ssid": "test-ht40",
  140. "channel": "1",
  141. "ht_capab": "[HT40+]"}
  142. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  143. state = hapd.get_status_field("state")
  144. if state != "HT_SCAN":
  145. time.sleep(0.1)
  146. state = hapd.get_status_field("state")
  147. if state != "HT_SCAN":
  148. raise Exception("Unexpected interface state - expected HT_SCAN")
  149. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  150. if not ev:
  151. raise Exception("AP setup timed out")
  152. state = hapd.get_status_field("state")
  153. if state != "ENABLED":
  154. raise Exception("Unexpected interface state - expected ENABLED")
  155. freq = hapd.get_status_field("freq")
  156. if freq != "2412":
  157. raise Exception("Unexpected frequency")
  158. pri = hapd.get_status_field("channel")
  159. if pri != "1":
  160. raise Exception("Unexpected primary channel")
  161. sec = hapd.get_status_field("secondary_channel")
  162. if sec != "1":
  163. raise Exception("Unexpected secondary channel: " + sec)
  164. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  165. @remote_compatible
  166. def test_ap_ht40_scan_legacy_conflict(dev, apdev):
  167. """HT40 co-ex scan conflict with legacy 20 MHz AP"""
  168. clear_scan_cache(apdev[0])
  169. params = { "ssid": "legacy-20",
  170. "channel": "7", "ieee80211n": "0" }
  171. hostapd.add_ap(apdev[1], params)
  172. params = { "ssid": "test-ht40",
  173. "channel": "5",
  174. "ht_capab": "[HT40-]"}
  175. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  176. state = hapd.get_status_field("state")
  177. if state != "HT_SCAN":
  178. time.sleep(0.1)
  179. state = hapd.get_status_field("state")
  180. if state != "HT_SCAN":
  181. raise Exception("Unexpected interface state - expected HT_SCAN")
  182. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  183. if not ev:
  184. raise Exception("AP setup timed out")
  185. state = hapd.get_status_field("state")
  186. if state != "ENABLED":
  187. raise Exception("Unexpected interface state - expected ENABLED")
  188. freq = hapd.get_status_field("freq")
  189. if freq != "2432":
  190. raise Exception("Unexpected frequency: " + freq)
  191. pri = hapd.get_status_field("channel")
  192. if pri != "5":
  193. raise Exception("Unexpected primary channel: " + pri)
  194. sec = hapd.get_status_field("secondary_channel")
  195. if sec != "0":
  196. raise Exception("Unexpected secondary channel: " + sec)
  197. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  198. @remote_compatible
  199. def test_ap_ht40_scan_ht20_conflict(dev, apdev):
  200. """HT40 co-ex scan conflict with HT 20 MHz AP"""
  201. clear_scan_cache(apdev[0])
  202. params = { "ssid": "ht-20",
  203. "channel": "7", "ieee80211n": "1" }
  204. hostapd.add_ap(apdev[1], params)
  205. params = { "ssid": "test-ht40",
  206. "channel": "5",
  207. "ht_capab": "[HT40-]"}
  208. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  209. state = hapd.get_status_field("state")
  210. if state != "HT_SCAN":
  211. time.sleep(0.1)
  212. state = hapd.get_status_field("state")
  213. if state != "HT_SCAN":
  214. raise Exception("Unexpected interface state - expected HT_SCAN")
  215. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  216. if not ev:
  217. raise Exception("AP setup timed out")
  218. state = hapd.get_status_field("state")
  219. if state != "ENABLED":
  220. raise Exception("Unexpected interface state - expected ENABLED")
  221. freq = hapd.get_status_field("freq")
  222. if freq != "2432":
  223. raise Exception("Unexpected frequency: " + freq)
  224. pri = hapd.get_status_field("channel")
  225. if pri != "5":
  226. raise Exception("Unexpected primary channel: " + pri)
  227. sec = hapd.get_status_field("secondary_channel")
  228. if sec != "0":
  229. raise Exception("Unexpected secondary channel: " + sec)
  230. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  231. def test_ap_ht40_scan_intolerant(dev, apdev):
  232. """HT40 co-ex scan finding an AP advertising 40 MHz intolerant"""
  233. clear_scan_cache(apdev[0])
  234. params = { "ssid": "another-bss",
  235. "channel": "1",
  236. "ht_capab": "[40-INTOLERANT]" }
  237. hostapd.add_ap(apdev[1], params)
  238. params = { "ssid": "test-ht40",
  239. "channel": "1",
  240. "ht_capab": "[HT40+]"}
  241. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  242. state = hapd.get_status_field("state")
  243. if state != "HT_SCAN":
  244. time.sleep(0.1)
  245. state = hapd.get_status_field("state")
  246. if state != "HT_SCAN":
  247. raise Exception("Unexpected interface state - expected HT_SCAN")
  248. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  249. if not ev:
  250. raise Exception("AP setup timed out")
  251. state = hapd.get_status_field("state")
  252. if state != "ENABLED":
  253. raise Exception("Unexpected interface state - expected ENABLED")
  254. freq = hapd.get_status_field("freq")
  255. if freq != "2412":
  256. raise Exception("Unexpected frequency: " + freq)
  257. pri = hapd.get_status_field("channel")
  258. if pri != "1":
  259. raise Exception("Unexpected primary channel: " + pri)
  260. sec = hapd.get_status_field("secondary_channel")
  261. if sec != "0":
  262. raise Exception("Unexpected secondary channel: " + sec)
  263. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  264. def test_ap_ht40_scan_match(dev, apdev):
  265. """HT40 co-ex scan matching configuration"""
  266. clear_scan_cache(apdev[0])
  267. params = { "ssid": "test-ht40",
  268. "channel": "5",
  269. "ht_capab": "[HT40-]"}
  270. hostapd.add_ap(apdev[1], params)
  271. params = { "ssid": "test-ht40",
  272. "channel": "5",
  273. "ht_capab": "[HT40-]"}
  274. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  275. state = hapd.get_status_field("state")
  276. if state != "HT_SCAN":
  277. time.sleep(0.1)
  278. state = hapd.get_status_field("state")
  279. if state != "HT_SCAN":
  280. raise Exception("Unexpected interface state - expected HT_SCAN")
  281. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  282. if not ev:
  283. raise Exception("AP setup timed out")
  284. state = hapd.get_status_field("state")
  285. if state != "ENABLED":
  286. raise Exception("Unexpected interface state - expected ENABLED")
  287. freq = hapd.get_status_field("freq")
  288. if freq != "2432":
  289. raise Exception("Unexpected frequency")
  290. pri = hapd.get_status_field("channel")
  291. if pri != "5":
  292. raise Exception("Unexpected primary channel")
  293. sec = hapd.get_status_field("secondary_channel")
  294. if sec != "-1":
  295. raise Exception("Unexpected secondary channel: " + sec)
  296. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  297. def test_ap_ht40_5ghz_match(dev, apdev):
  298. """HT40 co-ex scan on 5 GHz with matching pri/sec channel"""
  299. clear_scan_cache(apdev[0])
  300. try:
  301. hapd = None
  302. hapd2 = None
  303. params = { "ssid": "test-ht40",
  304. "hw_mode": "a",
  305. "channel": "36",
  306. "country_code": "US",
  307. "ht_capab": "[HT40+]"}
  308. hapd2 = hostapd.add_ap(apdev[1], params)
  309. params = { "ssid": "test-ht40",
  310. "hw_mode": "a",
  311. "channel": "36",
  312. "ht_capab": "[HT40+]"}
  313. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  314. state = hapd.get_status_field("state")
  315. if state != "HT_SCAN":
  316. time.sleep(0.1)
  317. state = hapd.get_status_field("state")
  318. if state != "HT_SCAN":
  319. raise Exception("Unexpected interface state - expected HT_SCAN")
  320. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  321. if not ev:
  322. raise Exception("AP setup timed out")
  323. state = hapd.get_status_field("state")
  324. if state != "ENABLED":
  325. raise Exception("Unexpected interface state - expected ENABLED")
  326. freq = hapd.get_status_field("freq")
  327. if freq != "5180":
  328. raise Exception("Unexpected frequency")
  329. pri = hapd.get_status_field("channel")
  330. if pri != "36":
  331. raise Exception("Unexpected primary channel")
  332. sec = hapd.get_status_field("secondary_channel")
  333. if sec != "1":
  334. raise Exception("Unexpected secondary channel: " + sec)
  335. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  336. finally:
  337. dev[0].request("DISCONNECT")
  338. if hapd:
  339. hapd.request("DISABLE")
  340. if hapd2:
  341. hapd2.request("DISABLE")
  342. set_world_reg(apdev[0], apdev[1], dev[0])
  343. dev[0].flush_scan_cache()
  344. def test_ap_ht40_5ghz_switch(dev, apdev):
  345. """HT40 co-ex scan on 5 GHz switching pri/sec channel"""
  346. clear_scan_cache(apdev[0])
  347. try:
  348. hapd = None
  349. hapd2 = None
  350. params = { "ssid": "test-ht40",
  351. "hw_mode": "a",
  352. "channel": "36",
  353. "country_code": "US",
  354. "ht_capab": "[HT40+]"}
  355. hapd2 = hostapd.add_ap(apdev[1], params)
  356. params = { "ssid": "test-ht40",
  357. "hw_mode": "a",
  358. "channel": "40",
  359. "ht_capab": "[HT40-]"}
  360. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  361. state = hapd.get_status_field("state")
  362. if state != "HT_SCAN":
  363. time.sleep(0.1)
  364. state = hapd.get_status_field("state")
  365. if state != "HT_SCAN":
  366. raise Exception("Unexpected interface state - expected HT_SCAN")
  367. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  368. if not ev:
  369. raise Exception("AP setup timed out")
  370. state = hapd.get_status_field("state")
  371. if state != "ENABLED":
  372. raise Exception("Unexpected interface state - expected ENABLED")
  373. freq = hapd.get_status_field("freq")
  374. if freq != "5180":
  375. raise Exception("Unexpected frequency: " + freq)
  376. pri = hapd.get_status_field("channel")
  377. if pri != "36":
  378. raise Exception("Unexpected primary channel: " + pri)
  379. sec = hapd.get_status_field("secondary_channel")
  380. if sec != "1":
  381. raise Exception("Unexpected secondary channel: " + sec)
  382. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  383. finally:
  384. dev[0].request("DISCONNECT")
  385. if hapd:
  386. hapd.request("DISABLE")
  387. if hapd2:
  388. hapd2.request("DISABLE")
  389. set_world_reg(apdev[0], apdev[1], dev[0])
  390. def test_ap_ht40_5ghz_switch2(dev, apdev):
  391. """HT40 co-ex scan on 5 GHz switching pri/sec channel (2)"""
  392. clear_scan_cache(apdev[0])
  393. try:
  394. hapd = None
  395. hapd2 = None
  396. params = { "ssid": "test-ht40",
  397. "hw_mode": "a",
  398. "channel": "36",
  399. "country_code": "US",
  400. "ht_capab": "[HT40+]"}
  401. hapd2 = hostapd.add_ap(apdev[1], params)
  402. id = dev[0].add_network()
  403. dev[0].set_network(id, "mode", "2")
  404. dev[0].set_network_quoted(id, "ssid", "wpas-ap-open")
  405. dev[0].set_network(id, "key_mgmt", "NONE")
  406. dev[0].set_network(id, "frequency", "5200")
  407. dev[0].set_network(id, "scan_freq", "5200")
  408. dev[0].select_network(id)
  409. time.sleep(1)
  410. params = { "ssid": "test-ht40",
  411. "hw_mode": "a",
  412. "channel": "40",
  413. "ht_capab": "[HT40-]"}
  414. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  415. state = hapd.get_status_field("state")
  416. if state != "HT_SCAN":
  417. time.sleep(0.1)
  418. state = hapd.get_status_field("state")
  419. if state != "HT_SCAN":
  420. raise Exception("Unexpected interface state - expected HT_SCAN")
  421. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  422. if not ev:
  423. raise Exception("AP setup timed out")
  424. state = hapd.get_status_field("state")
  425. if state != "ENABLED":
  426. raise Exception("Unexpected interface state - expected ENABLED")
  427. freq = hapd.get_status_field("freq")
  428. if freq != "5180":
  429. raise Exception("Unexpected frequency: " + freq)
  430. pri = hapd.get_status_field("channel")
  431. if pri != "36":
  432. raise Exception("Unexpected primary channel: " + pri)
  433. sec = hapd.get_status_field("secondary_channel")
  434. if sec != "1":
  435. raise Exception("Unexpected secondary channel: " + sec)
  436. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  437. finally:
  438. dev[0].request("DISCONNECT")
  439. if hapd:
  440. hapd.request("DISABLE")
  441. if hapd2:
  442. hapd2.request("DISABLE")
  443. set_world_reg(apdev[0], apdev[1], dev[0])
  444. dev[0].flush_scan_cache()
  445. def test_obss_scan(dev, apdev):
  446. """Overlapping BSS scan request"""
  447. params = { "ssid": "obss-scan",
  448. "channel": "6",
  449. "ht_capab": "[HT40-]",
  450. "obss_interval": "10" }
  451. hapd = hostapd.add_ap(apdev[0], params)
  452. params = { "ssid": "another-bss",
  453. "channel": "9",
  454. "ieee80211n": "0" }
  455. hostapd.add_ap(apdev[1], params)
  456. run_obss_scan(hapd, dev)
  457. def test_obss_scan_ht40_plus(dev, apdev):
  458. """Overlapping BSS scan request (HT40+)"""
  459. params = { "ssid": "obss-scan",
  460. "channel": "6",
  461. "ht_capab": "[HT40+]",
  462. "obss_interval": "10" }
  463. hapd = hostapd.add_ap(apdev[0], params)
  464. params = { "ssid": "another-bss",
  465. "channel": "9",
  466. "ieee80211n": "0" }
  467. hostapd.add_ap(apdev[1], params)
  468. run_obss_scan(hapd, dev)
  469. def run_obss_scan(hapd, dev):
  470. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  471. hapd.set("ext_mgmt_frame_handling", "1")
  472. logger.info("Waiting for OBSS scan to occur")
  473. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
  474. if ev is None:
  475. raise Exception("Timed out while waiting for OBSS scan to start")
  476. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
  477. if ev is None:
  478. raise Exception("Timed out while waiting for OBSS scan results")
  479. received = False
  480. for i in range(0, 4):
  481. frame = hapd.mgmt_rx(timeout=5)
  482. if frame is None:
  483. raise Exception("MGMT RX wait timed out")
  484. if frame['subtype'] != 13:
  485. continue
  486. payload = frame['payload']
  487. if len(payload) < 3:
  488. continue
  489. (category, action, ie) = struct.unpack('BBB', payload[0:3])
  490. if category != 4:
  491. continue
  492. if action != 0:
  493. continue
  494. if ie == 72:
  495. logger.info("20/40 BSS Coexistence report received")
  496. received = True
  497. break
  498. if not received:
  499. raise Exception("20/40 BSS Coexistence report not seen")
  500. def test_obss_scan_40_intolerant(dev, apdev):
  501. """Overlapping BSS scan request with 40 MHz intolerant AP"""
  502. params = { "ssid": "obss-scan",
  503. "channel": "6",
  504. "ht_capab": "[HT40-]",
  505. "obss_interval": "10" }
  506. hapd = hostapd.add_ap(apdev[0], params)
  507. params = { "ssid": "another-bss",
  508. "channel": "7",
  509. "ht_capab": "[40-INTOLERANT]" }
  510. hostapd.add_ap(apdev[1], params)
  511. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  512. hapd.set("ext_mgmt_frame_handling", "1")
  513. logger.info("Waiting for OBSS scan to occur")
  514. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
  515. if ev is None:
  516. raise Exception("Timed out while waiting for OBSS scan to start")
  517. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
  518. if ev is None:
  519. raise Exception("Timed out while waiting for OBSS scan results")
  520. received = False
  521. for i in range(0, 4):
  522. frame = hapd.mgmt_rx(timeout=5)
  523. if frame is None:
  524. raise Exception("MGMT RX wait timed out")
  525. if frame['subtype'] != 13:
  526. continue
  527. payload = frame['payload']
  528. if len(payload) < 3:
  529. continue
  530. (category, action, ie) = struct.unpack('BBB', payload[0:3])
  531. if category != 4:
  532. continue
  533. if action != 0:
  534. continue
  535. if ie == 72:
  536. logger.info("20/40 BSS Coexistence report received")
  537. received = True
  538. break
  539. if not received:
  540. raise Exception("20/40 BSS Coexistence report not seen")
  541. def test_obss_coex_report_handling(dev, apdev):
  542. """Overlapping BSS scan report handling with obss_interval=0"""
  543. clear_scan_cache(apdev[0])
  544. params = { "ssid": "obss-scan",
  545. "channel": "6",
  546. "ht_capab": "[HT40-]" }
  547. hapd = hostapd.add_ap(apdev[0], params)
  548. bssid = apdev[0]['bssid']
  549. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  550. sec = hapd.get_status_field("secondary_channel")
  551. if sec != "-1":
  552. raise Exception("AP is not using 40 MHz channel")
  553. # 20/40 MHz co-ex report tests: number of invalid reports and a valid report
  554. # that forces 20 MHz channel.
  555. tests = [ '0400', '040048', '04004801', '0400480000', '0400490100',
  556. '040048ff0000', '04004801ff49ff00', '04004801004900',
  557. '0400480100490101', '0400480100490201ff',
  558. '040048010449020005' ]
  559. for msg in tests:
  560. req = "MGMT_TX {} {} freq=2437 action={}".format(bssid, bssid, msg)
  561. if "OK" not in dev[0].request(req):
  562. raise Exception("Could not send management frame")
  563. time.sleep(0.5)
  564. sec = hapd.get_status_field("secondary_channel")
  565. if sec != "0":
  566. raise Exception("AP did not move to 20 MHz channel")
  567. def test_obss_coex_report_handling1(dev, apdev):
  568. """Overlapping BSS scan report handling with obss_interval=1"""
  569. clear_scan_cache(apdev[0])
  570. params = { "ssid": "obss-scan",
  571. "channel": "6",
  572. "ht_capab": "[HT40+]",
  573. "obss_interval": "1" }
  574. hapd = hostapd.add_ap(apdev[0], params)
  575. bssid = apdev[0]['bssid']
  576. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  577. sec = hapd.get_status_field("secondary_channel")
  578. if sec != "1":
  579. raise Exception("AP is not using 40 MHz channel")
  580. # 20/40 MHz co-ex report forcing 20 MHz channel
  581. msg = '040048010449020005'
  582. req = "MGMT_TX {} {} freq=2437 action={}".format(bssid, bssid, msg)
  583. if "OK" not in dev[0].request(req):
  584. raise Exception("Could not send management frame")
  585. time.sleep(0.5)
  586. sec = hapd.get_status_field("secondary_channel")
  587. if sec != "0":
  588. raise Exception("AP did not move to 20 MHz channel")
  589. # No 20/40 MHz co-ex reports forcing 20 MHz channel during next interval
  590. for i in range(20):
  591. sec = hapd.get_status_field("secondary_channel")
  592. if sec == "1":
  593. break
  594. time.sleep(0.5)
  595. if sec != "1":
  596. raise Exception("AP did not return to 40 MHz channel")
  597. def test_olbc(dev, apdev):
  598. """OLBC detection"""
  599. params = { "ssid": "test-olbc",
  600. "channel": "6",
  601. "ht_capab": "[HT40-]",
  602. "ap_table_expiration_time": "2" }
  603. hapd = hostapd.add_ap(apdev[0], params)
  604. status = hapd.get_status()
  605. if status['olbc'] != '0' or status['olbc_ht'] != '0':
  606. raise Exception("Unexpected OLBC information")
  607. params = { "ssid": "olbc-ap",
  608. "hw_mode": "b",
  609. "channel": "6",
  610. "wmm_enabled": "0" }
  611. hostapd.add_ap(apdev[1], params)
  612. time.sleep(0.5)
  613. status = hapd.get_status()
  614. if status['olbc'] != '1' or status['olbc_ht'] != '1':
  615. raise Exception("Missing OLBC information")
  616. hostapd.remove_bss(apdev[1])
  617. logger.info("Waiting for OLBC state to time out")
  618. cleared = False
  619. for i in range(0, 15):
  620. time.sleep(1)
  621. status = hapd.get_status()
  622. if status['olbc'] == '0' and status['olbc_ht'] == '0':
  623. cleared = True
  624. break
  625. if not cleared:
  626. raise Exception("OLBC state did nto time out")
  627. def test_olbc_table_limit(dev, apdev):
  628. """OLBC AP table size limit"""
  629. ifname1 = apdev[0]['ifname']
  630. ifname2 = apdev[0]['ifname'] + '-2'
  631. ifname3 = apdev[0]['ifname'] + '-3'
  632. hostapd.add_bss(apdev[0], ifname1, 'bss-1.conf')
  633. hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf')
  634. hostapd.add_bss(apdev[0], ifname3, 'bss-3.conf')
  635. params = { "ssid": "test-olbc",
  636. "channel": "1",
  637. "ap_table_max_size": "2" }
  638. hapd = hostapd.add_ap(apdev[1], params)
  639. time.sleep(0.3)
  640. with alloc_fail(hapd, 1, "ap_list_process_beacon"):
  641. time.sleep(0.3)
  642. hapd.set("ap_table_max_size", "1")
  643. time.sleep(0.3)
  644. hapd.set("ap_table_max_size", "0")
  645. time.sleep(0.3)
  646. def test_olbc_5ghz(dev, apdev):
  647. """OLBC detection on 5 GHz"""
  648. try:
  649. hapd = None
  650. hapd2 = None
  651. params = { "ssid": "test-olbc",
  652. "country_code": "FI",
  653. "hw_mode": "a",
  654. "channel": "36",
  655. "ht_capab": "[HT40+]" }
  656. hapd = hostapd.add_ap(apdev[0], params)
  657. status = hapd.get_status()
  658. if status['olbc'] != '0' or status['olbc_ht'] != '0':
  659. raise Exception("Unexpected OLBC information")
  660. params = { "ssid": "olbc-ap",
  661. "country_code": "FI",
  662. "hw_mode": "a",
  663. "channel": "36",
  664. "ieee80211n": "0",
  665. "wmm_enabled": "0" }
  666. hapd2 = hostapd.add_ap(apdev[1], params)
  667. found = False
  668. for i in range(20):
  669. time.sleep(0.1)
  670. status = hapd.get_status()
  671. logger.debug('olbc_ht: ' + status['olbc_ht'])
  672. if status['olbc_ht'] == '1':
  673. found = True
  674. break
  675. if not found:
  676. raise Exception("Missing OLBC information")
  677. finally:
  678. if hapd:
  679. hapd.request("DISABLE")
  680. if hapd2:
  681. hapd2.request("DISABLE")
  682. set_world_reg(apdev[0], apdev[1], None)
  683. def test_ap_require_ht(dev, apdev):
  684. """Require HT"""
  685. params = { "ssid": "require-ht",
  686. "require_ht": "1" }
  687. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  688. dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  689. disable_ht="1", wait_connect=False)
  690. dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
  691. ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
  692. dev[1].request("DISCONNECT")
  693. if ev is None:
  694. raise Exception("Association rejection timed out")
  695. if "status_code=27" not in ev:
  696. raise Exception("Unexpected rejection status code")
  697. dev[2].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  698. ht_mcs="0x01 00 00 00 00 00 00 00 00 00",
  699. disable_max_amsdu="1", ampdu_factor="2",
  700. ampdu_density="1", disable_ht40="1", disable_sgi="1",
  701. disable_ldpc="1")
  702. @remote_compatible
  703. def test_ap_require_ht_limited_rates(dev, apdev):
  704. """Require HT with limited supported rates"""
  705. params = { "ssid": "require-ht",
  706. "supported_rates": "60 120 240 360 480 540",
  707. "require_ht": "1" }
  708. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  709. dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  710. disable_ht="1", wait_connect=False)
  711. dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
  712. ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
  713. dev[1].request("DISCONNECT")
  714. if ev is None:
  715. raise Exception("Association rejection timed out")
  716. if "status_code=27" not in ev:
  717. raise Exception("Unexpected rejection status code")
  718. @remote_compatible
  719. def test_ap_ht_capab_not_supported(dev, apdev):
  720. """HT configuration with driver not supporting all ht_capab entries"""
  721. params = { "ssid": "test-ht40",
  722. "channel": "5",
  723. "ht_capab": "[HT40-][LDPC][SMPS-STATIC][SMPS-DYNAMIC][GF][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC1][RX-STBC12][RX-STBC123][DELAYED-BA][MAX-AMSDU-7935][DSSS_CCK-40][LSIG-TXOP-PROT]"}
  724. hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
  725. if "FAIL" not in hapd.request("ENABLE"):
  726. raise Exception("Unexpected ENABLE success")
  727. def test_ap_ht_40mhz_intolerant_sta(dev, apdev):
  728. """Associated STA indicating 40 MHz intolerant"""
  729. clear_scan_cache(apdev[0])
  730. params = { "ssid": "intolerant",
  731. "channel": "6",
  732. "ht_capab": "[HT40-]" }
  733. hapd = hostapd.add_ap(apdev[0], params)
  734. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  735. raise Exception("Unexpected num_sta_ht40_intolerant value")
  736. if hapd.get_status_field("secondary_channel") != "-1":
  737. raise Exception("Unexpected secondary_channel")
  738. dev[0].connect("intolerant", key_mgmt="NONE", scan_freq="2437")
  739. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  740. raise Exception("Unexpected num_sta_ht40_intolerant value")
  741. if hapd.get_status_field("secondary_channel") != "-1":
  742. raise Exception("Unexpected secondary_channel")
  743. dev[2].connect("intolerant", key_mgmt="NONE", scan_freq="2437",
  744. ht40_intolerant="1")
  745. time.sleep(1)
  746. if hapd.get_status_field("num_sta_ht40_intolerant") != "1":
  747. raise Exception("Unexpected num_sta_ht40_intolerant value (expected 1)")
  748. if hapd.get_status_field("secondary_channel") != "0":
  749. raise Exception("Unexpected secondary_channel (did not disable 40 MHz)")
  750. dev[2].request("DISCONNECT")
  751. time.sleep(1)
  752. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  753. raise Exception("Unexpected num_sta_ht40_intolerant value (expected 0)")
  754. if hapd.get_status_field("secondary_channel") != "-1":
  755. raise Exception("Unexpected secondary_channel (did not re-enable 40 MHz)")
  756. def test_ap_ht_40mhz_intolerant_ap(dev, apdev):
  757. """Associated STA reports 40 MHz intolerant AP after association"""
  758. clear_scan_cache(apdev[0])
  759. params = { "ssid": "ht",
  760. "channel": "6",
  761. "ht_capab": "[HT40-]",
  762. "obss_interval": "3" }
  763. hapd = hostapd.add_ap(apdev[0], params)
  764. dev[0].connect("ht", key_mgmt="NONE", scan_freq="2437")
  765. if hapd.get_status_field("secondary_channel") != "-1":
  766. raise Exception("Unexpected secondary channel information")
  767. logger.info("Start 40 MHz intolerant AP")
  768. params = { "ssid": "intolerant",
  769. "channel": "5",
  770. "ht_capab": "[40-INTOLERANT]" }
  771. hapd2 = hostapd.add_ap(apdev[1], params)
  772. logger.info("Waiting for co-ex report from STA")
  773. ok = False
  774. for i in range(0, 20):
  775. time.sleep(1)
  776. if hapd.get_status_field("secondary_channel") == "0":
  777. logger.info("AP moved to 20 MHz channel")
  778. ok = True
  779. break
  780. if not ok:
  781. raise Exception("AP did not move to 20 MHz channel")
  782. if "OK" not in hapd2.request("DISABLE"):
  783. raise Exception("Failed to disable 40 MHz intolerant AP")
  784. # make sure the intolerant AP disappears from scan results more quickly
  785. dev[0].scan(type="ONLY", freq="2432", only_new=True)
  786. dev[0].scan(type="ONLY", freq="2432", only_new=True)
  787. dev[0].dump_monitor()
  788. logger.info("Waiting for AP to move back to 40 MHz channel")
  789. ok = False
  790. for i in range(0, 30):
  791. time.sleep(1)
  792. if hapd.get_status_field("secondary_channel") == "-1":
  793. logger.info("AP moved to 40 MHz channel")
  794. ok = True
  795. break
  796. if not ok:
  797. raise Exception("AP did not move to 40 MHz channel")
  798. def test_ap_ht40_csa(dev, apdev):
  799. """HT with 40 MHz channel width and CSA"""
  800. csa_supported(dev[0])
  801. try:
  802. hapd = None
  803. params = { "ssid": "ht",
  804. "country_code": "US",
  805. "hw_mode": "a",
  806. "channel": "36",
  807. "ht_capab": "[HT40+]",
  808. "ieee80211n": "1" }
  809. hapd = hostapd.add_ap(apdev[0], params)
  810. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  811. hwsim_utils.test_connectivity(dev[0], hapd)
  812. hapd.request("CHAN_SWITCH 5 5200 ht sec_channel_offset=-1 bandwidth=40")
  813. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  814. if ev is None:
  815. raise Exception("CSA finished event timed out")
  816. if "freq=5200" not in ev:
  817. raise Exception("Unexpected channel in CSA finished event")
  818. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  819. if ev is not None:
  820. raise Exception("Unexpected STA disconnection during CSA")
  821. hwsim_utils.test_connectivity(dev[0], hapd)
  822. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  823. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  824. if ev is None:
  825. raise Exception("CSA finished event timed out")
  826. if "freq=5180" not in ev:
  827. raise Exception("Unexpected channel in CSA finished event")
  828. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  829. if ev is not None:
  830. raise Exception("Unexpected STA disconnection during CSA")
  831. hwsim_utils.test_connectivity(dev[0], hapd)
  832. finally:
  833. dev[0].request("DISCONNECT")
  834. if hapd:
  835. hapd.request("DISABLE")
  836. set_world_reg(apdev[0], None, dev[0])
  837. dev[0].flush_scan_cache()
  838. def test_ap_ht40_csa2(dev, apdev):
  839. """HT with 40 MHz channel width and CSA"""
  840. csa_supported(dev[0])
  841. try:
  842. hapd = None
  843. params = { "ssid": "ht",
  844. "country_code": "US",
  845. "hw_mode": "a",
  846. "channel": "36",
  847. "ht_capab": "[HT40+]",
  848. "ieee80211n": "1" }
  849. hapd = hostapd.add_ap(apdev[0], params)
  850. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  851. hwsim_utils.test_connectivity(dev[0], hapd)
  852. hapd.request("CHAN_SWITCH 5 5220 ht sec_channel_offset=1 bandwidth=40")
  853. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  854. if ev is None:
  855. raise Exception("CSA finished event timed out")
  856. if "freq=5220" not in ev:
  857. raise Exception("Unexpected channel in CSA finished event")
  858. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  859. if ev is not None:
  860. raise Exception("Unexpected STA disconnection during CSA")
  861. hwsim_utils.test_connectivity(dev[0], hapd)
  862. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  863. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  864. if ev is None:
  865. raise Exception("CSA finished event timed out")
  866. if "freq=5180" not in ev:
  867. raise Exception("Unexpected channel in CSA finished event")
  868. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  869. if ev is not None:
  870. raise Exception("Unexpected STA disconnection during CSA")
  871. hwsim_utils.test_connectivity(dev[0], hapd)
  872. finally:
  873. dev[0].request("DISCONNECT")
  874. if hapd:
  875. hapd.request("DISABLE")
  876. set_world_reg(apdev[0], None, dev[0])
  877. dev[0].flush_scan_cache()
  878. def test_ap_ht40_csa3(dev, apdev):
  879. """HT with 40 MHz channel width and CSA"""
  880. csa_supported(dev[0])
  881. try:
  882. hapd = None
  883. params = { "ssid": "ht",
  884. "country_code": "US",
  885. "hw_mode": "a",
  886. "channel": "36",
  887. "ht_capab": "[HT40+]",
  888. "ieee80211n": "1" }
  889. hapd = hostapd.add_ap(apdev[0], params)
  890. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  891. hwsim_utils.test_connectivity(dev[0], hapd)
  892. hapd.request("CHAN_SWITCH 5 5240 ht sec_channel_offset=-1 bandwidth=40")
  893. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  894. if ev is None:
  895. raise Exception("CSA finished event timed out")
  896. if "freq=5240" not in ev:
  897. raise Exception("Unexpected channel in CSA finished event")
  898. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  899. if ev is not None:
  900. raise Exception("Unexpected STA disconnection during CSA")
  901. hwsim_utils.test_connectivity(dev[0], hapd)
  902. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  903. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  904. if ev is None:
  905. raise Exception("CSA finished event timed out")
  906. if "freq=5180" not in ev:
  907. raise Exception("Unexpected channel in CSA finished event")
  908. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  909. if ev is not None:
  910. raise Exception("Unexpected STA disconnection during CSA")
  911. hwsim_utils.test_connectivity(dev[0], hapd)
  912. finally:
  913. dev[0].request("DISCONNECT")
  914. if hapd:
  915. hapd.request("DISABLE")
  916. set_world_reg(apdev[0], None, dev[0])
  917. dev[0].flush_scan_cache()
  918. @remote_compatible
  919. def test_ap_ht_smps(dev, apdev):
  920. """SMPS AP configuration options"""
  921. params = { "ssid": "ht1", "ht_capab": "[SMPS-STATIC]" }
  922. try:
  923. hapd = hostapd.add_ap(apdev[0], params)
  924. except:
  925. raise HwsimSkip("Assume mac80211_hwsim was not recent enough to support SMPS")
  926. params = { "ssid": "ht2", "ht_capab": "[SMPS-DYNAMIC]" }
  927. hapd2 = hostapd.add_ap(apdev[1], params)
  928. dev[0].connect("ht1", key_mgmt="NONE", scan_freq="2412")
  929. dev[1].connect("ht2", key_mgmt="NONE", scan_freq="2412")
  930. hwsim_utils.test_connectivity(dev[0], hapd)
  931. hwsim_utils.test_connectivity(dev[1], hapd2)
  932. @remote_compatible
  933. def test_prefer_ht20(dev, apdev):
  934. """Preference on HT20 over no-HT"""
  935. params = { "ssid": "test",
  936. "channel": "1",
  937. "ieee80211n": "0" }
  938. hapd = hostapd.add_ap(apdev[0], params)
  939. bssid = apdev[0]['bssid']
  940. params = { "ssid": "test",
  941. "channel": "1",
  942. "ieee80211n": "1" }
  943. hapd2 = hostapd.add_ap(apdev[1], params)
  944. bssid2 = apdev[1]['bssid']
  945. dev[0].scan_for_bss(bssid, freq=2412)
  946. dev[0].scan_for_bss(bssid2, freq=2412)
  947. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  948. if dev[0].get_status_field('bssid') != bssid2:
  949. raise Exception("Unexpected BSS selected")
  950. est = dev[0].get_bss(bssid)['est_throughput']
  951. if est != "54000":
  952. raise Exception("Unexpected BSS0 est_throughput: " + est)
  953. est = dev[0].get_bss(bssid2)['est_throughput']
  954. if est != "65000":
  955. raise Exception("Unexpected BSS1 est_throughput: " + est)
  956. def test_prefer_ht40(dev, apdev):
  957. """Preference on HT40 over HT20"""
  958. params = { "ssid": "test",
  959. "channel": "1",
  960. "ieee80211n": "1" }
  961. hapd = hostapd.add_ap(apdev[0], params)
  962. bssid = apdev[0]['bssid']
  963. params = { "ssid": "test",
  964. "channel": "1",
  965. "ieee80211n": "1",
  966. "ht_capab": "[HT40+]" }
  967. hapd2 = hostapd.add_ap(apdev[1], params)
  968. bssid2 = apdev[1]['bssid']
  969. dev[0].scan_for_bss(bssid, freq=2412)
  970. dev[0].scan_for_bss(bssid2, freq=2412)
  971. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  972. if dev[0].get_status_field('bssid') != bssid2:
  973. raise Exception("Unexpected BSS selected")
  974. est = dev[0].get_bss(bssid)['est_throughput']
  975. if est != "65000":
  976. raise Exception("Unexpected BSS0 est_throughput: " + est)
  977. est = dev[0].get_bss(bssid2)['est_throughput']
  978. if est != "135000":
  979. raise Exception("Unexpected BSS1 est_throughput: " + est)
  980. @remote_compatible
  981. def test_prefer_ht20_during_roam(dev, apdev):
  982. """Preference on HT20 over no-HT in roaming consideration"""
  983. params = { "ssid": "test",
  984. "channel": "1",
  985. "ieee80211n": "0" }
  986. hapd = hostapd.add_ap(apdev[0], params)
  987. bssid = apdev[0]['bssid']
  988. dev[0].scan_for_bss(bssid, freq=2412)
  989. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  990. params = { "ssid": "test",
  991. "channel": "1",
  992. "ieee80211n": "1" }
  993. hapd2 = hostapd.add_ap(apdev[1], params)
  994. bssid2 = apdev[1]['bssid']
  995. dev[0].scan_for_bss(bssid2, freq=2412)
  996. dev[0].scan(freq=2412)
  997. dev[0].wait_connected()
  998. if dev[0].get_status_field('bssid') != bssid2:
  999. raise Exception("Unexpected BSS selected")
  1000. @remote_compatible
  1001. def test_ap_ht40_5ghz_invalid_pair(dev, apdev):
  1002. """HT40 on 5 GHz with invalid channel pair"""
  1003. clear_scan_cache(apdev[0])
  1004. try:
  1005. params = { "ssid": "test-ht40",
  1006. "hw_mode": "a",
  1007. "channel": "40",
  1008. "country_code": "US",
  1009. "ht_capab": "[HT40+]"}
  1010. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  1011. ev = hapd.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout=10)
  1012. if not ev:
  1013. raise Exception("AP setup failure timed out")
  1014. if "AP-ENABLED" in ev:
  1015. sec = hapd.get_status_field("secondary_channel")
  1016. if sec != "0":
  1017. raise Exception("Invalid 40 MHz channel accepted")
  1018. finally:
  1019. set_world_reg(apdev[0], None, None)
  1020. @remote_compatible
  1021. def test_ap_ht40_5ghz_disabled_sec(dev, apdev):
  1022. """HT40 on 5 GHz with disabled secondary channel"""
  1023. clear_scan_cache(apdev[0])
  1024. try:
  1025. params = { "ssid": "test-ht40",
  1026. "hw_mode": "a",
  1027. "channel": "48",
  1028. "country_code": "US",
  1029. "ht_capab": "[HT40+]"}
  1030. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  1031. ev = hapd.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout=10)
  1032. if not ev:
  1033. raise Exception("AP setup failure timed out")
  1034. if "AP-ENABLED" in ev:
  1035. sec = hapd.get_status_field("secondary_channel")
  1036. if sec != "0":
  1037. raise Exception("Invalid 40 MHz channel accepted")
  1038. finally:
  1039. set_world_reg(apdev[0], None, None)
  1040. def test_ap_ht40_scan_broken_ap(dev, apdev):
  1041. """HT40 co-ex scan and broken legacy/HT AP"""
  1042. clear_scan_cache(apdev[0])
  1043. # Broken AP: Include HT Capabilities element but not HT Operation element
  1044. params = { "ssid": "legacy-20",
  1045. "channel": "7", "ieee80211n": "0",
  1046. "wmm_enabled": "1",
  1047. "vendor_elements": "2d1a0e001bffff000000000000000000000100000000000000000000" }
  1048. hapd2 = hostapd.add_ap(apdev[1], params)
  1049. params = { "ssid": "test-ht40",
  1050. "channel": "5",
  1051. "ht_capab": "[HT40-]"}
  1052. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  1053. state = hapd.get_status_field("state")
  1054. if state != "HT_SCAN":
  1055. time.sleep(0.1)
  1056. state = hapd.get_status_field("state")
  1057. if state != "HT_SCAN":
  1058. raise Exception("Unexpected interface state - expected HT_SCAN")
  1059. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  1060. if not ev:
  1061. raise Exception("AP setup timed out")
  1062. state = hapd.get_status_field("state")
  1063. if state != "ENABLED":
  1064. raise Exception("Unexpected interface state - expected ENABLED")
  1065. freq = hapd.get_status_field("freq")
  1066. if freq != "2432":
  1067. raise Exception("Unexpected frequency: " + freq)
  1068. pri = hapd.get_status_field("channel")
  1069. if pri != "5":
  1070. raise Exception("Unexpected primary channel: " + pri)
  1071. sec = hapd.get_status_field("secondary_channel")
  1072. if sec != "-1":
  1073. raise Exception("Unexpected secondary channel: " + sec)
  1074. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  1075. dev[1].connect("legacy-20", key_mgmt="NONE", scan_freq="2442")
  1076. hwsim_utils.test_connectivity(dev[0], hapd)
  1077. hwsim_utils.test_connectivity(dev[1], hapd2)
  1078. def run_op_class(dev, apdev, hw_mode, channel, country, ht_capab, sec_chan,
  1079. freq, opclass):
  1080. clear_scan_cache(apdev[0])
  1081. try:
  1082. params = { "ssid": "test-ht40",
  1083. "hw_mode": hw_mode,
  1084. "channel": channel,
  1085. "ht_capab": ht_capab }
  1086. if country:
  1087. params['country_code'] = country
  1088. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  1089. ev = hapd.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout=10)
  1090. if not ev:
  1091. raise Exception("AP setup failure timed out")
  1092. if "AP-DISABLED" in ev:
  1093. raise HwsimSkip("Channel not supported")
  1094. sec = hapd.get_status_field("secondary_channel")
  1095. if sec != sec_chan:
  1096. raise Exception("Unexpected secondary_channel: " + sec)
  1097. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  1098. bss = dev[0].get_bss(hapd.own_addr())
  1099. ie = parse_ie(bss['ie'])
  1100. if 59 not in ie:
  1101. raise Exception("Missing Supported Operating Classes element")
  1102. rx_opclass, = struct.unpack('B', ie[59][0:1])
  1103. if rx_opclass != opclass:
  1104. raise Exception("Unexpected operating class: %d" % rx_opclass)
  1105. finally:
  1106. set_world_reg(apdev[0], None, None)
  1107. def test_ap_ht_op_class_81(dev, apdev):
  1108. """HT20 on operationg class 81"""
  1109. run_op_class(dev, apdev, "g", "1", None, "", "0", "2412", 81)
  1110. def test_ap_ht_op_class_83(dev, apdev):
  1111. """HT40 on operationg class 83"""
  1112. run_op_class(dev, apdev, "g", "1", None, "[HT40+]", "1", "2412", 83)
  1113. def test_ap_ht_op_class_84(dev, apdev):
  1114. """HT40 on operationg class 84"""
  1115. run_op_class(dev, apdev, "g", "11", None, "[HT40-]", "-1", "2462", 84)
  1116. def test_ap_ht_op_class_115(dev, apdev):
  1117. """HT20 on operationg class 115"""
  1118. run_op_class(dev, apdev, "a", "36", "FI", "", "0", "5180", 115)
  1119. def test_ap_ht_op_class_116(dev, apdev):
  1120. """HT40 on operationg class 116"""
  1121. run_op_class(dev, apdev, "a", "36", "FI", "[HT40+]", "1", "5180", 116)
  1122. def test_ap_ht_op_class_117(dev, apdev):
  1123. """HT40 on operationg class 117"""
  1124. run_op_class(dev, apdev, "a", "40", "FI", "[HT40-]", "-1", "5200", 117)
  1125. def test_ap_ht_op_class_118(dev, apdev):
  1126. """HT20 on operationg class 118"""
  1127. run_op_class(dev, apdev, "a", "60", "RS", "", "0", "5300", 118)
  1128. def test_ap_ht_op_class_119(dev, apdev):
  1129. """HT40 on operationg class 119"""
  1130. run_op_class(dev, apdev, "a", "60", "RS", "[HT40+]", "1", "5300", 119)
  1131. def test_ap_ht_op_class_120(dev, apdev):
  1132. """HT40 on operationg class 120"""
  1133. run_op_class(dev, apdev, "a", "64", "RS", "[HT40-]", "-1", "5320", 120)
  1134. def test_ap_ht_op_class_121(dev, apdev):
  1135. """HT20 on operationg class 121"""
  1136. run_op_class(dev, apdev, "a", "100", "ZA", "", "0", "5500", 121)
  1137. def test_ap_ht_op_class_122(dev, apdev):
  1138. """HT40 on operationg class 122"""
  1139. run_op_class(dev, apdev, "a", "100", "ZA", "[HT40+]", "1", "5500", 122)
  1140. def test_ap_ht_op_class_123(dev, apdev):
  1141. """HT40 on operationg class 123"""
  1142. run_op_class(dev, apdev, "a", "104", "ZA", "[HT40-]", "-1", "5520", 123)
  1143. def test_ap_ht_op_class_124(dev, apdev):
  1144. """HT20 on operationg class 124"""
  1145. run_op_class(dev, apdev, "a", "149", "US", "", "0", "5745", 124)
  1146. def test_ap_ht_op_class_125(dev, apdev):
  1147. """HT20 on operationg class 125"""
  1148. run_op_class(dev, apdev, "a", "169", "NL", "", "0", "5845", 125)
  1149. def test_ap_ht_op_class_126(dev, apdev):
  1150. """HT40 on operationg class 126"""
  1151. run_op_class(dev, apdev, "a", "149", "US", "[HT40+]", "1", "5745", 126)
  1152. def test_ap_ht_op_class_127(dev, apdev):
  1153. """HT40 on operationg class 127"""
  1154. run_op_class(dev, apdev, "a", "153", "US", "[HT40-]", "-1", "5765", 127)
  1155. def test_ap_ht40_plus_minus1(dev, apdev):
  1156. """HT40 with both plus and minus allowed (1)"""
  1157. clear_scan_cache(apdev[0])
  1158. params = { "ssid": "test-ht40",
  1159. "channel": "11",
  1160. "ht_capab": "[HT40+][HT40-]"}
  1161. hapd = hostapd.add_ap(apdev[0], params)
  1162. freq = hapd.get_status_field("freq")
  1163. if freq != "2462":
  1164. raise Exception("Unexpected frequency: " + freq)
  1165. pri = hapd.get_status_field("channel")
  1166. if pri != "11":
  1167. raise Exception("Unexpected primary channel: " + pri)
  1168. sec = hapd.get_status_field("secondary_channel")
  1169. if sec != "-1":
  1170. raise Exception("Unexpected secondary channel: " + sec)
  1171. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  1172. def test_ap_ht40_plus_minus2(dev, apdev):
  1173. """HT40 with both plus and minus allowed (2)"""
  1174. clear_scan_cache(apdev[0])
  1175. params = { "ssid": "test-ht40",
  1176. "channel": "1",
  1177. "ht_capab": "[HT40+][HT40-]"}
  1178. hapd = hostapd.add_ap(apdev[0], params)
  1179. freq = hapd.get_status_field("freq")
  1180. if freq != "2412":
  1181. raise Exception("Unexpected frequency: " + freq)
  1182. pri = hapd.get_status_field("channel")
  1183. if pri != "1":
  1184. raise Exception("Unexpected primary channel: " + pri)
  1185. sec = hapd.get_status_field("secondary_channel")
  1186. if sec != "1":
  1187. raise Exception("Unexpected secondary channel: " + sec)
  1188. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)