test_ap_ht.py 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130
  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. import time
  7. import logging
  8. logger = logging.getLogger()
  9. import struct
  10. import subprocess
  11. import hostapd
  12. from utils import HwsimSkip, alloc_fail
  13. import hwsim_utils
  14. from test_ap_csa import csa_supported
  15. def clear_scan_cache(ifname):
  16. subprocess.call(['ifconfig', ifname, 'up'])
  17. subprocess.call(['iw', ifname, 'scan', 'trigger', 'freq', '2412', 'flush'])
  18. time.sleep(0.1)
  19. subprocess.call(['ifconfig', ifname, 'down'])
  20. def test_ap_ht40_scan(dev, apdev):
  21. """HT40 co-ex scan"""
  22. clear_scan_cache(apdev[0]['ifname'])
  23. params = { "ssid": "test-ht40",
  24. "channel": "5",
  25. "ht_capab": "[HT40-]"}
  26. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  27. state = hapd.get_status_field("state")
  28. if state != "HT_SCAN":
  29. time.sleep(0.1)
  30. state = hapd.get_status_field("state")
  31. if state != "HT_SCAN":
  32. raise Exception("Unexpected interface state - expected HT_SCAN")
  33. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  34. if not ev:
  35. raise Exception("AP setup timed out")
  36. state = hapd.get_status_field("state")
  37. if state != "ENABLED":
  38. raise Exception("Unexpected interface state - expected ENABLED")
  39. freq = hapd.get_status_field("freq")
  40. if freq != "2432":
  41. raise Exception("Unexpected frequency")
  42. pri = hapd.get_status_field("channel")
  43. if pri != "5":
  44. raise Exception("Unexpected primary channel")
  45. sec = hapd.get_status_field("secondary_channel")
  46. if sec != "-1":
  47. raise Exception("Unexpected secondary channel")
  48. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  49. def test_ap_ht40_scan_conflict(dev, apdev):
  50. """HT40 co-ex scan conflict"""
  51. clear_scan_cache(apdev[0]['ifname'])
  52. params = { "ssid": "test-ht40",
  53. "channel": "6",
  54. "ht_capab": "[HT40+]"}
  55. hostapd.add_ap(apdev[1]['ifname'], params)
  56. params = { "ssid": "test-ht40",
  57. "channel": "5",
  58. "ht_capab": "[HT40-]"}
  59. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  60. state = hapd.get_status_field("state")
  61. if state != "HT_SCAN":
  62. time.sleep(0.1)
  63. state = hapd.get_status_field("state")
  64. if state != "HT_SCAN":
  65. raise Exception("Unexpected interface state - expected HT_SCAN")
  66. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  67. if not ev:
  68. raise Exception("AP setup timed out")
  69. state = hapd.get_status_field("state")
  70. if state != "ENABLED":
  71. raise Exception("Unexpected interface state - expected ENABLED")
  72. freq = hapd.get_status_field("freq")
  73. if freq != "2432":
  74. raise Exception("Unexpected frequency")
  75. pri = hapd.get_status_field("channel")
  76. if pri != "5":
  77. raise Exception("Unexpected primary channel")
  78. sec = hapd.get_status_field("secondary_channel")
  79. if sec != "0":
  80. raise Exception("Unexpected secondary channel: " + sec)
  81. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  82. def test_ap_ht40_scan_conflict2(dev, apdev):
  83. """HT40 co-ex scan conflict (HT40-)"""
  84. clear_scan_cache(apdev[0]['ifname'])
  85. params = { "ssid": "test-ht40",
  86. "channel": "11",
  87. "ht_capab": "[HT40-]"}
  88. hostapd.add_ap(apdev[1]['ifname'], params)
  89. params = { "ssid": "test-ht40",
  90. "channel": "1",
  91. "ht_capab": "[HT40+]"}
  92. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  93. state = hapd.get_status_field("state")
  94. if state != "HT_SCAN":
  95. time.sleep(0.1)
  96. state = hapd.get_status_field("state")
  97. if state != "HT_SCAN":
  98. raise Exception("Unexpected interface state - expected HT_SCAN")
  99. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  100. if not ev:
  101. raise Exception("AP setup timed out")
  102. state = hapd.get_status_field("state")
  103. if state != "ENABLED":
  104. raise Exception("Unexpected interface state - expected ENABLED")
  105. freq = hapd.get_status_field("freq")
  106. if freq != "2412":
  107. raise Exception("Unexpected frequency")
  108. pri = hapd.get_status_field("channel")
  109. if pri != "1":
  110. raise Exception("Unexpected primary channel")
  111. sec = hapd.get_status_field("secondary_channel")
  112. if sec != "0":
  113. raise Exception("Unexpected secondary channel: " + sec)
  114. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  115. def test_ap_ht40_scan_not_affected(dev, apdev):
  116. """HT40 co-ex scan and other BSS not affected"""
  117. clear_scan_cache(apdev[0]['ifname'])
  118. params = { "ssid": "test-ht20",
  119. "channel": "11" }
  120. hostapd.add_ap(apdev[1]['ifname'], params)
  121. subprocess.call(['ifconfig', apdev[0]['ifname'], 'up'])
  122. subprocess.call(['iw', apdev[0]['ifname'], 'scan', 'trigger', 'freq', '2462'])
  123. time.sleep(0.5)
  124. subprocess.call(['iw', apdev[0]['ifname'], 'scan', 'dump'],
  125. stdout=open('/dev/null', 'w'))
  126. time.sleep(0.1)
  127. subprocess.call(['ifconfig', apdev[0]['ifname'], 'down'])
  128. params = { "ssid": "test-ht40",
  129. "channel": "1",
  130. "ht_capab": "[HT40+]"}
  131. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  132. state = hapd.get_status_field("state")
  133. if state != "HT_SCAN":
  134. time.sleep(0.1)
  135. state = hapd.get_status_field("state")
  136. if state != "HT_SCAN":
  137. raise Exception("Unexpected interface state - expected HT_SCAN")
  138. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  139. if not ev:
  140. raise Exception("AP setup timed out")
  141. state = hapd.get_status_field("state")
  142. if state != "ENABLED":
  143. raise Exception("Unexpected interface state - expected ENABLED")
  144. freq = hapd.get_status_field("freq")
  145. if freq != "2412":
  146. raise Exception("Unexpected frequency")
  147. pri = hapd.get_status_field("channel")
  148. if pri != "1":
  149. raise Exception("Unexpected primary channel")
  150. sec = hapd.get_status_field("secondary_channel")
  151. if sec != "1":
  152. raise Exception("Unexpected secondary channel: " + sec)
  153. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  154. def test_ap_ht40_scan_legacy_conflict(dev, apdev):
  155. """HT40 co-ex scan conflict with legacy 20 MHz AP"""
  156. clear_scan_cache(apdev[0]['ifname'])
  157. params = { "ssid": "legacy-20",
  158. "channel": "7", "ieee80211n": "0" }
  159. hostapd.add_ap(apdev[1]['ifname'], params)
  160. params = { "ssid": "test-ht40",
  161. "channel": "5",
  162. "ht_capab": "[HT40-]"}
  163. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  164. state = hapd.get_status_field("state")
  165. if state != "HT_SCAN":
  166. time.sleep(0.1)
  167. state = hapd.get_status_field("state")
  168. if state != "HT_SCAN":
  169. raise Exception("Unexpected interface state - expected HT_SCAN")
  170. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  171. if not ev:
  172. raise Exception("AP setup timed out")
  173. state = hapd.get_status_field("state")
  174. if state != "ENABLED":
  175. raise Exception("Unexpected interface state - expected ENABLED")
  176. freq = hapd.get_status_field("freq")
  177. if freq != "2432":
  178. raise Exception("Unexpected frequency: " + freq)
  179. pri = hapd.get_status_field("channel")
  180. if pri != "5":
  181. raise Exception("Unexpected primary channel: " + pri)
  182. sec = hapd.get_status_field("secondary_channel")
  183. if sec != "0":
  184. raise Exception("Unexpected secondary channel: " + sec)
  185. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  186. def test_ap_ht40_scan_ht20_conflict(dev, apdev):
  187. """HT40 co-ex scan conflict with HT 20 MHz AP"""
  188. clear_scan_cache(apdev[0]['ifname'])
  189. params = { "ssid": "ht-20",
  190. "channel": "7", "ieee80211n": "1" }
  191. hostapd.add_ap(apdev[1]['ifname'], params)
  192. params = { "ssid": "test-ht40",
  193. "channel": "5",
  194. "ht_capab": "[HT40-]"}
  195. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  196. state = hapd.get_status_field("state")
  197. if state != "HT_SCAN":
  198. time.sleep(0.1)
  199. state = hapd.get_status_field("state")
  200. if state != "HT_SCAN":
  201. raise Exception("Unexpected interface state - expected HT_SCAN")
  202. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  203. if not ev:
  204. raise Exception("AP setup timed out")
  205. state = hapd.get_status_field("state")
  206. if state != "ENABLED":
  207. raise Exception("Unexpected interface state - expected ENABLED")
  208. freq = hapd.get_status_field("freq")
  209. if freq != "2432":
  210. raise Exception("Unexpected frequency: " + freq)
  211. pri = hapd.get_status_field("channel")
  212. if pri != "5":
  213. raise Exception("Unexpected primary channel: " + pri)
  214. sec = hapd.get_status_field("secondary_channel")
  215. if sec != "0":
  216. raise Exception("Unexpected secondary channel: " + sec)
  217. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  218. def test_ap_ht40_scan_intolerant(dev, apdev):
  219. """HT40 co-ex scan finding an AP advertising 40 MHz intolerant"""
  220. clear_scan_cache(apdev[0]['ifname'])
  221. params = { "ssid": "another-bss",
  222. "channel": "1",
  223. "ht_capab": "[40-INTOLERANT]" }
  224. hostapd.add_ap(apdev[1]['ifname'], params)
  225. params = { "ssid": "test-ht40",
  226. "channel": "1",
  227. "ht_capab": "[HT40+]"}
  228. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  229. state = hapd.get_status_field("state")
  230. if state != "HT_SCAN":
  231. time.sleep(0.1)
  232. state = hapd.get_status_field("state")
  233. if state != "HT_SCAN":
  234. raise Exception("Unexpected interface state - expected HT_SCAN")
  235. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  236. if not ev:
  237. raise Exception("AP setup timed out")
  238. state = hapd.get_status_field("state")
  239. if state != "ENABLED":
  240. raise Exception("Unexpected interface state - expected ENABLED")
  241. freq = hapd.get_status_field("freq")
  242. if freq != "2412":
  243. raise Exception("Unexpected frequency: " + freq)
  244. pri = hapd.get_status_field("channel")
  245. if pri != "1":
  246. raise Exception("Unexpected primary channel: " + pri)
  247. sec = hapd.get_status_field("secondary_channel")
  248. if sec != "0":
  249. raise Exception("Unexpected secondary channel: " + sec)
  250. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  251. def test_ap_ht40_scan_match(dev, apdev):
  252. """HT40 co-ex scan matching configuration"""
  253. clear_scan_cache(apdev[0]['ifname'])
  254. params = { "ssid": "test-ht40",
  255. "channel": "5",
  256. "ht_capab": "[HT40-]"}
  257. hostapd.add_ap(apdev[1]['ifname'], params)
  258. params = { "ssid": "test-ht40",
  259. "channel": "5",
  260. "ht_capab": "[HT40-]"}
  261. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  262. state = hapd.get_status_field("state")
  263. if state != "HT_SCAN":
  264. time.sleep(0.1)
  265. state = hapd.get_status_field("state")
  266. if state != "HT_SCAN":
  267. raise Exception("Unexpected interface state - expected HT_SCAN")
  268. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  269. if not ev:
  270. raise Exception("AP setup timed out")
  271. state = hapd.get_status_field("state")
  272. if state != "ENABLED":
  273. raise Exception("Unexpected interface state - expected ENABLED")
  274. freq = hapd.get_status_field("freq")
  275. if freq != "2432":
  276. raise Exception("Unexpected frequency")
  277. pri = hapd.get_status_field("channel")
  278. if pri != "5":
  279. raise Exception("Unexpected primary channel")
  280. sec = hapd.get_status_field("secondary_channel")
  281. if sec != "-1":
  282. raise Exception("Unexpected secondary channel: " + sec)
  283. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  284. def test_ap_ht40_5ghz_match(dev, apdev):
  285. """HT40 co-ex scan on 5 GHz with matching pri/sec channel"""
  286. clear_scan_cache(apdev[0]['ifname'])
  287. try:
  288. hapd = None
  289. hapd2 = None
  290. params = { "ssid": "test-ht40",
  291. "hw_mode": "a",
  292. "channel": "36",
  293. "country_code": "US",
  294. "ht_capab": "[HT40+]"}
  295. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  296. params = { "ssid": "test-ht40",
  297. "hw_mode": "a",
  298. "channel": "36",
  299. "ht_capab": "[HT40+]"}
  300. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  301. state = hapd.get_status_field("state")
  302. if state != "HT_SCAN":
  303. time.sleep(0.1)
  304. state = hapd.get_status_field("state")
  305. if state != "HT_SCAN":
  306. raise Exception("Unexpected interface state - expected HT_SCAN")
  307. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  308. if not ev:
  309. raise Exception("AP setup timed out")
  310. state = hapd.get_status_field("state")
  311. if state != "ENABLED":
  312. raise Exception("Unexpected interface state - expected ENABLED")
  313. freq = hapd.get_status_field("freq")
  314. if freq != "5180":
  315. raise Exception("Unexpected frequency")
  316. pri = hapd.get_status_field("channel")
  317. if pri != "36":
  318. raise Exception("Unexpected primary channel")
  319. sec = hapd.get_status_field("secondary_channel")
  320. if sec != "1":
  321. raise Exception("Unexpected secondary channel: " + sec)
  322. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  323. finally:
  324. dev[0].request("DISCONNECT")
  325. if hapd:
  326. hapd.request("DISABLE")
  327. if hapd2:
  328. hapd2.request("DISABLE")
  329. subprocess.call(['iw', 'reg', 'set', '00'])
  330. dev[0].flush_scan_cache()
  331. def test_ap_ht40_5ghz_switch(dev, apdev):
  332. """HT40 co-ex scan on 5 GHz switching pri/sec channel"""
  333. clear_scan_cache(apdev[0]['ifname'])
  334. try:
  335. hapd = None
  336. hapd2 = None
  337. params = { "ssid": "test-ht40",
  338. "hw_mode": "a",
  339. "channel": "36",
  340. "country_code": "US",
  341. "ht_capab": "[HT40+]"}
  342. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  343. params = { "ssid": "test-ht40",
  344. "hw_mode": "a",
  345. "channel": "40",
  346. "ht_capab": "[HT40-]"}
  347. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  348. state = hapd.get_status_field("state")
  349. if state != "HT_SCAN":
  350. time.sleep(0.1)
  351. state = hapd.get_status_field("state")
  352. if state != "HT_SCAN":
  353. raise Exception("Unexpected interface state - expected HT_SCAN")
  354. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  355. if not ev:
  356. raise Exception("AP setup timed out")
  357. state = hapd.get_status_field("state")
  358. if state != "ENABLED":
  359. raise Exception("Unexpected interface state - expected ENABLED")
  360. freq = hapd.get_status_field("freq")
  361. if freq != "5180":
  362. raise Exception("Unexpected frequency: " + freq)
  363. pri = hapd.get_status_field("channel")
  364. if pri != "36":
  365. raise Exception("Unexpected primary channel: " + pri)
  366. sec = hapd.get_status_field("secondary_channel")
  367. if sec != "1":
  368. raise Exception("Unexpected secondary channel: " + sec)
  369. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  370. finally:
  371. dev[0].request("DISCONNECT")
  372. if hapd:
  373. hapd.request("DISABLE")
  374. if hapd2:
  375. hapd2.request("DISABLE")
  376. subprocess.call(['iw', 'reg', 'set', '00'])
  377. def test_ap_ht40_5ghz_switch2(dev, apdev):
  378. """HT40 co-ex scan on 5 GHz switching pri/sec channel (2)"""
  379. clear_scan_cache(apdev[0]['ifname'])
  380. try:
  381. hapd = None
  382. hapd2 = None
  383. params = { "ssid": "test-ht40",
  384. "hw_mode": "a",
  385. "channel": "36",
  386. "country_code": "US",
  387. "ht_capab": "[HT40+]"}
  388. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  389. id = dev[0].add_network()
  390. dev[0].set_network(id, "mode", "2")
  391. dev[0].set_network_quoted(id, "ssid", "wpas-ap-open")
  392. dev[0].set_network(id, "key_mgmt", "NONE")
  393. dev[0].set_network(id, "frequency", "5200")
  394. dev[0].set_network(id, "scan_freq", "5200")
  395. dev[0].select_network(id)
  396. time.sleep(1)
  397. params = { "ssid": "test-ht40",
  398. "hw_mode": "a",
  399. "channel": "40",
  400. "ht_capab": "[HT40-]"}
  401. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  402. state = hapd.get_status_field("state")
  403. if state != "HT_SCAN":
  404. time.sleep(0.1)
  405. state = hapd.get_status_field("state")
  406. if state != "HT_SCAN":
  407. raise Exception("Unexpected interface state - expected HT_SCAN")
  408. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  409. if not ev:
  410. raise Exception("AP setup timed out")
  411. state = hapd.get_status_field("state")
  412. if state != "ENABLED":
  413. raise Exception("Unexpected interface state - expected ENABLED")
  414. freq = hapd.get_status_field("freq")
  415. if freq != "5180":
  416. raise Exception("Unexpected frequency: " + freq)
  417. pri = hapd.get_status_field("channel")
  418. if pri != "36":
  419. raise Exception("Unexpected primary channel: " + pri)
  420. sec = hapd.get_status_field("secondary_channel")
  421. if sec != "1":
  422. raise Exception("Unexpected secondary channel: " + sec)
  423. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  424. finally:
  425. dev[0].request("DISCONNECT")
  426. if hapd:
  427. hapd.request("DISABLE")
  428. if hapd2:
  429. hapd2.request("DISABLE")
  430. subprocess.call(['iw', 'reg', 'set', '00'])
  431. dev[0].flush_scan_cache()
  432. def test_obss_scan(dev, apdev):
  433. """Overlapping BSS scan request"""
  434. params = { "ssid": "obss-scan",
  435. "channel": "6",
  436. "ht_capab": "[HT40-]",
  437. "obss_interval": "10" }
  438. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  439. params = { "ssid": "another-bss",
  440. "channel": "9",
  441. "ieee80211n": "0" }
  442. hostapd.add_ap(apdev[1]['ifname'], params)
  443. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  444. hapd.set("ext_mgmt_frame_handling", "1")
  445. logger.info("Waiting for OBSS scan to occur")
  446. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
  447. if ev is None:
  448. raise Exception("Timed out while waiting for OBSS scan to start")
  449. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
  450. if ev is None:
  451. raise Exception("Timed out while waiting for OBSS scan results")
  452. received = False
  453. for i in range(0, 4):
  454. frame = hapd.mgmt_rx(timeout=5)
  455. if frame is None:
  456. raise Exception("MGMT RX wait timed out")
  457. if frame['subtype'] != 13:
  458. continue
  459. payload = frame['payload']
  460. if len(payload) < 3:
  461. continue
  462. (category, action, ie) = struct.unpack('BBB', payload[0:3])
  463. if category != 4:
  464. continue
  465. if action != 0:
  466. continue
  467. if ie == 72:
  468. logger.info("20/40 BSS Coexistence report received")
  469. received = True
  470. break
  471. if not received:
  472. raise Exception("20/40 BSS Coexistence report not seen")
  473. def test_obss_scan_40_intolerant(dev, apdev):
  474. """Overlapping BSS scan request with 40 MHz intolerant AP"""
  475. params = { "ssid": "obss-scan",
  476. "channel": "6",
  477. "ht_capab": "[HT40-]",
  478. "obss_interval": "10" }
  479. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  480. params = { "ssid": "another-bss",
  481. "channel": "7",
  482. "ht_capab": "[40-INTOLERANT]" }
  483. hostapd.add_ap(apdev[1]['ifname'], params)
  484. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  485. hapd.set("ext_mgmt_frame_handling", "1")
  486. logger.info("Waiting for OBSS scan to occur")
  487. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
  488. if ev is None:
  489. raise Exception("Timed out while waiting for OBSS scan to start")
  490. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
  491. if ev is None:
  492. raise Exception("Timed out while waiting for OBSS scan results")
  493. received = False
  494. for i in range(0, 4):
  495. frame = hapd.mgmt_rx(timeout=5)
  496. if frame is None:
  497. raise Exception("MGMT RX wait timed out")
  498. if frame['subtype'] != 13:
  499. continue
  500. payload = frame['payload']
  501. if len(payload) < 3:
  502. continue
  503. (category, action, ie) = struct.unpack('BBB', payload[0:3])
  504. if category != 4:
  505. continue
  506. if action != 0:
  507. continue
  508. if ie == 72:
  509. logger.info("20/40 BSS Coexistence report received")
  510. received = True
  511. break
  512. if not received:
  513. raise Exception("20/40 BSS Coexistence report not seen")
  514. def test_obss_coex_report_handling(dev, apdev):
  515. """Overlapping BSS scan report handling with obss_interval=0"""
  516. clear_scan_cache(apdev[0]['ifname'])
  517. params = { "ssid": "obss-scan",
  518. "channel": "6",
  519. "ht_capab": "[HT40-]" }
  520. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  521. bssid = apdev[0]['bssid']
  522. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  523. sec = hapd.get_status_field("secondary_channel")
  524. if sec != "-1":
  525. raise Exception("AP is not using 40 MHz channel")
  526. # 20/40 MHz co-ex report tests: number of invalid reports and a valid report
  527. # that forces 20 MHz channel.
  528. tests = [ '0400', '040048', '04004801', '0400480000', '0400490100',
  529. '040048ff0000', '04004801ff49ff00', '04004801004900',
  530. '0400480100490101', '0400480100490201ff',
  531. '040048010449020005' ]
  532. for msg in tests:
  533. req = "MGMT_TX {} {} freq=2437 action={}".format(bssid, bssid, msg)
  534. if "OK" not in dev[0].request(req):
  535. raise Exception("Could not send management frame")
  536. time.sleep(0.5)
  537. sec = hapd.get_status_field("secondary_channel")
  538. if sec != "0":
  539. raise Exception("AP did not move to 20 MHz channel")
  540. def test_obss_coex_report_handling1(dev, apdev):
  541. """Overlapping BSS scan report handling with obss_interval=1"""
  542. clear_scan_cache(apdev[0]['ifname'])
  543. params = { "ssid": "obss-scan",
  544. "channel": "6",
  545. "ht_capab": "[HT40+]",
  546. "obss_interval": "1" }
  547. hapd = hostapd.add_ap(apdev[0]['ifname'], 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 forcing 20 MHz channel
  554. msg = '040048010449020005'
  555. req = "MGMT_TX {} {} freq=2437 action={}".format(bssid, bssid, msg)
  556. if "OK" not in dev[0].request(req):
  557. raise Exception("Could not send management frame")
  558. time.sleep(0.5)
  559. sec = hapd.get_status_field("secondary_channel")
  560. if sec != "0":
  561. raise Exception("AP did not move to 20 MHz channel")
  562. # No 20/40 MHz co-ex reports forcing 20 MHz channel during next interval
  563. for i in range(20):
  564. sec = hapd.get_status_field("secondary_channel")
  565. if sec == "1":
  566. break
  567. time.sleep(0.5)
  568. if sec != "1":
  569. raise Exception("AP did not return to 40 MHz channel")
  570. def test_olbc(dev, apdev):
  571. """OLBC detection"""
  572. params = { "ssid": "test-olbc",
  573. "channel": "6",
  574. "ht_capab": "[HT40-]",
  575. "ap_table_expiration_time": "2" }
  576. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  577. status = hapd.get_status()
  578. if status['olbc'] != '0' or status['olbc_ht'] != '0':
  579. raise Exception("Unexpected OLBC information")
  580. params = { "ssid": "olbc-ap",
  581. "hw_mode": "b",
  582. "channel": "6",
  583. "wmm_enabled": "0" }
  584. hostapd.add_ap(apdev[1]['ifname'], params)
  585. time.sleep(0.5)
  586. status = hapd.get_status()
  587. if status['olbc'] != '1' or status['olbc_ht'] != '1':
  588. raise Exception("Missing OLBC information")
  589. hapd_global = hostapd.HostapdGlobal()
  590. hapd_global.remove(apdev[1]['ifname'])
  591. logger.info("Waiting for OLBC state to time out")
  592. cleared = False
  593. for i in range(0, 15):
  594. time.sleep(1)
  595. status = hapd.get_status()
  596. if status['olbc'] == '0' and status['olbc_ht'] == '0':
  597. cleared = True
  598. break
  599. if not cleared:
  600. raise Exception("OLBC state did nto time out")
  601. def test_olbc_table_limit(dev, apdev):
  602. """OLBC AP table size limit"""
  603. ifname1 = apdev[0]['ifname']
  604. ifname2 = apdev[0]['ifname'] + '-2'
  605. ifname3 = apdev[0]['ifname'] + '-3'
  606. hostapd.add_bss('phy3', ifname1, 'bss-1.conf')
  607. hostapd.add_bss('phy3', ifname2, 'bss-2.conf')
  608. hostapd.add_bss('phy3', ifname3, 'bss-3.conf')
  609. params = { "ssid": "test-olbc",
  610. "channel": "1",
  611. "ap_table_max_size": "2" }
  612. hapd = hostapd.add_ap(apdev[1]['ifname'], params)
  613. time.sleep(0.3)
  614. with alloc_fail(hapd, 1, "ap_list_process_beacon"):
  615. time.sleep(0.3)
  616. hapd.set("ap_table_max_size", "1")
  617. time.sleep(0.3)
  618. hapd.set("ap_table_max_size", "0")
  619. time.sleep(0.3)
  620. def test_olbc_5ghz(dev, apdev):
  621. """OLBC detection on 5 GHz"""
  622. try:
  623. hapd = None
  624. hapd2 = None
  625. params = { "ssid": "test-olbc",
  626. "country_code": "FI",
  627. "hw_mode": "a",
  628. "channel": "36",
  629. "ht_capab": "[HT40+]" }
  630. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  631. status = hapd.get_status()
  632. if status['olbc'] != '0' or status['olbc_ht'] != '0':
  633. raise Exception("Unexpected OLBC information")
  634. params = { "ssid": "olbc-ap",
  635. "country_code": "FI",
  636. "hw_mode": "a",
  637. "channel": "36",
  638. "ieee80211n": "0",
  639. "wmm_enabled": "0" }
  640. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  641. found = False
  642. for i in range(20):
  643. time.sleep(0.1)
  644. status = hapd.get_status()
  645. logger.debug('olbc_ht: ' + status['olbc_ht'])
  646. if status['olbc_ht'] == '1':
  647. found = True
  648. break
  649. if not found:
  650. raise Exception("Missing OLBC information")
  651. finally:
  652. if hapd:
  653. hapd.request("DISABLE")
  654. if hapd2:
  655. hapd2.request("DISABLE")
  656. subprocess.call(['iw', 'reg', 'set', '00'])
  657. def test_ap_require_ht(dev, apdev):
  658. """Require HT"""
  659. params = { "ssid": "require-ht",
  660. "require_ht": "1" }
  661. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  662. dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  663. disable_ht="1", wait_connect=False)
  664. dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
  665. ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
  666. dev[1].request("DISCONNECT")
  667. if ev is None:
  668. raise Exception("Association rejection timed out")
  669. if "status_code=27" not in ev:
  670. raise Exception("Unexpected rejection status code")
  671. dev[2].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  672. ht_mcs="0x01 00 00 00 00 00 00 00 00 00",
  673. disable_max_amsdu="1", ampdu_factor="2",
  674. ampdu_density="1", disable_ht40="1", disable_sgi="1",
  675. disable_ldpc="1")
  676. def test_ap_require_ht_limited_rates(dev, apdev):
  677. """Require HT with limited supported rates"""
  678. params = { "ssid": "require-ht",
  679. "supported_rates": "60 120 240 360 480 540",
  680. "require_ht": "1" }
  681. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  682. dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  683. disable_ht="1", wait_connect=False)
  684. dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
  685. ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
  686. dev[1].request("DISCONNECT")
  687. if ev is None:
  688. raise Exception("Association rejection timed out")
  689. if "status_code=27" not in ev:
  690. raise Exception("Unexpected rejection status code")
  691. def test_ap_ht_capab_not_supported(dev, apdev):
  692. """HT configuration with driver not supporting all ht_capab entries"""
  693. params = { "ssid": "test-ht40",
  694. "channel": "5",
  695. "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]"}
  696. hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
  697. if "FAIL" not in hapd.request("ENABLE"):
  698. raise Exception("Unexpected ENABLE success")
  699. def test_ap_ht_40mhz_intolerant_sta(dev, apdev):
  700. """Associated STA indicating 40 MHz intolerant"""
  701. clear_scan_cache(apdev[0]['ifname'])
  702. params = { "ssid": "intolerant",
  703. "channel": "6",
  704. "ht_capab": "[HT40-]" }
  705. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  706. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  707. raise Exception("Unexpected num_sta_ht40_intolerant value")
  708. if hapd.get_status_field("secondary_channel") != "-1":
  709. raise Exception("Unexpected secondary_channel")
  710. dev[0].connect("intolerant", key_mgmt="NONE", scan_freq="2437")
  711. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  712. raise Exception("Unexpected num_sta_ht40_intolerant value")
  713. if hapd.get_status_field("secondary_channel") != "-1":
  714. raise Exception("Unexpected secondary_channel")
  715. dev[2].connect("intolerant", key_mgmt="NONE", scan_freq="2437",
  716. ht40_intolerant="1")
  717. time.sleep(1)
  718. if hapd.get_status_field("num_sta_ht40_intolerant") != "1":
  719. raise Exception("Unexpected num_sta_ht40_intolerant value (expected 1)")
  720. if hapd.get_status_field("secondary_channel") != "0":
  721. raise Exception("Unexpected secondary_channel (did not disable 40 MHz)")
  722. dev[2].request("DISCONNECT")
  723. time.sleep(1)
  724. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  725. raise Exception("Unexpected num_sta_ht40_intolerant value (expected 0)")
  726. if hapd.get_status_field("secondary_channel") != "-1":
  727. raise Exception("Unexpected secondary_channel (did not re-enable 40 MHz)")
  728. def test_ap_ht_40mhz_intolerant_ap(dev, apdev):
  729. """Associated STA reports 40 MHz intolerant AP after association"""
  730. clear_scan_cache(apdev[0]['ifname'])
  731. params = { "ssid": "ht",
  732. "channel": "6",
  733. "ht_capab": "[HT40-]",
  734. "obss_interval": "3" }
  735. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  736. dev[0].connect("ht", key_mgmt="NONE", scan_freq="2437")
  737. if hapd.get_status_field("secondary_channel") != "-1":
  738. raise Exception("Unexpected secondary channel information")
  739. logger.info("Start 40 MHz intolerant AP")
  740. params = { "ssid": "intolerant",
  741. "channel": "5",
  742. "ht_capab": "[40-INTOLERANT]" }
  743. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  744. logger.info("Waiting for co-ex report from STA")
  745. ok = False
  746. for i in range(0, 20):
  747. time.sleep(1)
  748. if hapd.get_status_field("secondary_channel") == "0":
  749. logger.info("AP moved to 20 MHz channel")
  750. ok = True
  751. break
  752. if not ok:
  753. raise Exception("AP did not move to 20 MHz channel")
  754. if "OK" not in hapd2.request("DISABLE"):
  755. raise Exception("Failed to disable 40 MHz intolerant AP")
  756. # make sure the intolerant AP disappears from scan results more quickly
  757. dev[0].scan(type="ONLY", freq="2432", only_new=True)
  758. dev[0].scan(type="ONLY", freq="2432", only_new=True)
  759. dev[0].dump_monitor()
  760. logger.info("Waiting for AP to move back to 40 MHz channel")
  761. ok = False
  762. for i in range(0, 30):
  763. time.sleep(1)
  764. if hapd.get_status_field("secondary_channel") == "-1":
  765. logger.info("AP moved to 40 MHz channel")
  766. ok = True
  767. break
  768. if not ok:
  769. raise Exception("AP did not move to 40 MHz channel")
  770. def test_ap_ht40_csa(dev, apdev):
  771. """HT with 40 MHz channel width and CSA"""
  772. csa_supported(dev[0])
  773. try:
  774. hapd = None
  775. params = { "ssid": "ht",
  776. "country_code": "US",
  777. "hw_mode": "a",
  778. "channel": "36",
  779. "ht_capab": "[HT40+]",
  780. "ieee80211n": "1" }
  781. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  782. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  783. hwsim_utils.test_connectivity(dev[0], hapd)
  784. hapd.request("CHAN_SWITCH 5 5200 ht sec_channel_offset=-1 bandwidth=40")
  785. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  786. if ev is None:
  787. raise Exception("CSA finished event timed out")
  788. if "freq=5200" not in ev:
  789. raise Exception("Unexpected channel in CSA finished event")
  790. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  791. if ev is not None:
  792. raise Exception("Unexpected STA disconnection during CSA")
  793. hwsim_utils.test_connectivity(dev[0], hapd)
  794. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  795. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  796. if ev is None:
  797. raise Exception("CSA finished event timed out")
  798. if "freq=5180" not in ev:
  799. raise Exception("Unexpected channel in CSA finished event")
  800. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  801. if ev is not None:
  802. raise Exception("Unexpected STA disconnection during CSA")
  803. hwsim_utils.test_connectivity(dev[0], hapd)
  804. finally:
  805. dev[0].request("DISCONNECT")
  806. if hapd:
  807. hapd.request("DISABLE")
  808. subprocess.call(['iw', 'reg', 'set', '00'])
  809. dev[0].flush_scan_cache()
  810. def test_ap_ht40_csa2(dev, apdev):
  811. """HT with 40 MHz channel width and CSA"""
  812. csa_supported(dev[0])
  813. try:
  814. hapd = None
  815. params = { "ssid": "ht",
  816. "country_code": "US",
  817. "hw_mode": "a",
  818. "channel": "36",
  819. "ht_capab": "[HT40+]",
  820. "ieee80211n": "1" }
  821. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  822. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  823. hwsim_utils.test_connectivity(dev[0], hapd)
  824. hapd.request("CHAN_SWITCH 5 5220 ht sec_channel_offset=1 bandwidth=40")
  825. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  826. if ev is None:
  827. raise Exception("CSA finished event timed out")
  828. if "freq=5220" not in ev:
  829. raise Exception("Unexpected channel in CSA finished event")
  830. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  831. if ev is not None:
  832. raise Exception("Unexpected STA disconnection during CSA")
  833. hwsim_utils.test_connectivity(dev[0], hapd)
  834. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  835. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  836. if ev is None:
  837. raise Exception("CSA finished event timed out")
  838. if "freq=5180" not in ev:
  839. raise Exception("Unexpected channel in CSA finished event")
  840. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  841. if ev is not None:
  842. raise Exception("Unexpected STA disconnection during CSA")
  843. hwsim_utils.test_connectivity(dev[0], hapd)
  844. finally:
  845. dev[0].request("DISCONNECT")
  846. if hapd:
  847. hapd.request("DISABLE")
  848. subprocess.call(['iw', 'reg', 'set', '00'])
  849. dev[0].flush_scan_cache()
  850. def test_ap_ht40_csa3(dev, apdev):
  851. """HT with 40 MHz channel width and CSA"""
  852. csa_supported(dev[0])
  853. try:
  854. hapd = None
  855. params = { "ssid": "ht",
  856. "country_code": "US",
  857. "hw_mode": "a",
  858. "channel": "36",
  859. "ht_capab": "[HT40+]",
  860. "ieee80211n": "1" }
  861. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  862. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  863. hwsim_utils.test_connectivity(dev[0], hapd)
  864. hapd.request("CHAN_SWITCH 5 5240 ht sec_channel_offset=-1 bandwidth=40")
  865. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  866. if ev is None:
  867. raise Exception("CSA finished event timed out")
  868. if "freq=5240" not in ev:
  869. raise Exception("Unexpected channel in CSA finished event")
  870. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  871. if ev is not None:
  872. raise Exception("Unexpected STA disconnection during CSA")
  873. hwsim_utils.test_connectivity(dev[0], hapd)
  874. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  875. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  876. if ev is None:
  877. raise Exception("CSA finished event timed out")
  878. if "freq=5180" not in ev:
  879. raise Exception("Unexpected channel in CSA finished event")
  880. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  881. if ev is not None:
  882. raise Exception("Unexpected STA disconnection during CSA")
  883. hwsim_utils.test_connectivity(dev[0], hapd)
  884. finally:
  885. dev[0].request("DISCONNECT")
  886. if hapd:
  887. hapd.request("DISABLE")
  888. subprocess.call(['iw', 'reg', 'set', '00'])
  889. dev[0].flush_scan_cache()
  890. def test_ap_ht_smps(dev, apdev):
  891. """SMPS AP configuration options"""
  892. params = { "ssid": "ht1", "ht_capab": "[SMPS-STATIC]" }
  893. try:
  894. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  895. except:
  896. raise HwsimSkip("Assume mac80211_hwsim was not recent enough to support SMPS")
  897. params = { "ssid": "ht2", "ht_capab": "[SMPS-DYNAMIC]" }
  898. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  899. dev[0].connect("ht1", key_mgmt="NONE", scan_freq="2412")
  900. dev[1].connect("ht2", key_mgmt="NONE", scan_freq="2412")
  901. hwsim_utils.test_connectivity(dev[0], hapd)
  902. hwsim_utils.test_connectivity(dev[1], hapd2)
  903. def test_prefer_ht20(dev, apdev):
  904. """Preference on HT20 over no-HT"""
  905. params = { "ssid": "test",
  906. "channel": "1",
  907. "ieee80211n": "0" }
  908. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  909. bssid = apdev[0]['bssid']
  910. params = { "ssid": "test",
  911. "channel": "1",
  912. "ieee80211n": "1" }
  913. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  914. bssid2 = apdev[1]['bssid']
  915. dev[0].scan_for_bss(bssid, freq=2412)
  916. dev[0].scan_for_bss(bssid2, freq=2412)
  917. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  918. if dev[0].get_status_field('bssid') != bssid2:
  919. raise Exception("Unexpected BSS selected")
  920. est = dev[0].get_bss(bssid)['est_throughput']
  921. if est != "54000":
  922. raise Exception("Unexpected BSS0 est_throughput: " + est)
  923. est = dev[0].get_bss(bssid2)['est_throughput']
  924. if est != "65000":
  925. raise Exception("Unexpected BSS1 est_throughput: " + est)
  926. def test_prefer_ht40(dev, apdev):
  927. """Preference on HT40 over HT20"""
  928. params = { "ssid": "test",
  929. "channel": "1",
  930. "ieee80211n": "1" }
  931. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  932. bssid = apdev[0]['bssid']
  933. params = { "ssid": "test",
  934. "channel": "1",
  935. "ieee80211n": "1",
  936. "ht_capab": "[HT40+]" }
  937. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  938. bssid2 = apdev[1]['bssid']
  939. dev[0].scan_for_bss(bssid, freq=2412)
  940. dev[0].scan_for_bss(bssid2, freq=2412)
  941. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  942. if dev[0].get_status_field('bssid') != bssid2:
  943. raise Exception("Unexpected BSS selected")
  944. est = dev[0].get_bss(bssid)['est_throughput']
  945. if est != "65000":
  946. raise Exception("Unexpected BSS0 est_throughput: " + est)
  947. est = dev[0].get_bss(bssid2)['est_throughput']
  948. if est != "135000":
  949. raise Exception("Unexpected BSS1 est_throughput: " + est)
  950. def test_prefer_ht20_during_roam(dev, apdev):
  951. """Preference on HT20 over no-HT in roaming consideration"""
  952. params = { "ssid": "test",
  953. "channel": "1",
  954. "ieee80211n": "0" }
  955. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  956. bssid = apdev[0]['bssid']
  957. dev[0].scan_for_bss(bssid, freq=2412)
  958. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  959. params = { "ssid": "test",
  960. "channel": "1",
  961. "ieee80211n": "1" }
  962. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  963. bssid2 = apdev[1]['bssid']
  964. dev[0].scan_for_bss(bssid2, freq=2412)
  965. dev[0].scan(freq=2412)
  966. dev[0].wait_connected()
  967. if dev[0].get_status_field('bssid') != bssid2:
  968. raise Exception("Unexpected BSS selected")
  969. def test_ap_ht40_5ghz_invalid_pair(dev, apdev):
  970. """HT40 on 5 GHz with invalid channel pair"""
  971. clear_scan_cache(apdev[0]['ifname'])
  972. try:
  973. params = { "ssid": "test-ht40",
  974. "hw_mode": "a",
  975. "channel": "40",
  976. "country_code": "US",
  977. "ht_capab": "[HT40+]"}
  978. hapd = hostapd.add_ap(apdev[1]['ifname'], params, wait_enabled=False)
  979. ev = hapd.wait_event(["AP-DISABLED"], timeout=10)
  980. if not ev:
  981. raise Exception("AP setup failure timed out")
  982. finally:
  983. subprocess.call(['iw', 'reg', 'set', '00'])