test_ap_ht.py 40 KB

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