test_ap_ht.py 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128
  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. if ev is None:
  667. raise Exception("Association rejection timed out")
  668. if "status_code=27" not in ev:
  669. raise Exception("Unexpected rejection status code")
  670. dev[2].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  671. ht_mcs="0x01 00 00 00 00 00 00 00 00 00",
  672. disable_max_amsdu="1", ampdu_factor="2",
  673. ampdu_density="1", disable_ht40="1", disable_sgi="1",
  674. disable_ldpc="1")
  675. def test_ap_require_ht_limited_rates(dev, apdev):
  676. """Require HT with limited supported rates"""
  677. params = { "ssid": "require-ht",
  678. "supported_rates": "60 120 240 360 480 540",
  679. "require_ht": "1" }
  680. hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
  681. dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  682. disable_ht="1", wait_connect=False)
  683. dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
  684. ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
  685. if ev is None:
  686. raise Exception("Association rejection timed out")
  687. if "status_code=27" not in ev:
  688. raise Exception("Unexpected rejection status code")
  689. def test_ap_ht_capab_not_supported(dev, apdev):
  690. """HT configuration with driver not supporting all ht_capab entries"""
  691. params = { "ssid": "test-ht40",
  692. "channel": "5",
  693. "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]"}
  694. hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
  695. if "FAIL" not in hapd.request("ENABLE"):
  696. raise Exception("Unexpected ENABLE success")
  697. def test_ap_ht_40mhz_intolerant_sta(dev, apdev):
  698. """Associated STA indicating 40 MHz intolerant"""
  699. clear_scan_cache(apdev[0]['ifname'])
  700. params = { "ssid": "intolerant",
  701. "channel": "6",
  702. "ht_capab": "[HT40-]" }
  703. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  704. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  705. raise Exception("Unexpected num_sta_ht40_intolerant value")
  706. if hapd.get_status_field("secondary_channel") != "-1":
  707. raise Exception("Unexpected secondary_channel")
  708. dev[0].connect("intolerant", key_mgmt="NONE", scan_freq="2437")
  709. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  710. raise Exception("Unexpected num_sta_ht40_intolerant value")
  711. if hapd.get_status_field("secondary_channel") != "-1":
  712. raise Exception("Unexpected secondary_channel")
  713. dev[2].connect("intolerant", key_mgmt="NONE", scan_freq="2437",
  714. ht40_intolerant="1")
  715. time.sleep(1)
  716. if hapd.get_status_field("num_sta_ht40_intolerant") != "1":
  717. raise Exception("Unexpected num_sta_ht40_intolerant value (expected 1)")
  718. if hapd.get_status_field("secondary_channel") != "0":
  719. raise Exception("Unexpected secondary_channel (did not disable 40 MHz)")
  720. dev[2].request("DISCONNECT")
  721. time.sleep(1)
  722. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  723. raise Exception("Unexpected num_sta_ht40_intolerant value (expected 0)")
  724. if hapd.get_status_field("secondary_channel") != "-1":
  725. raise Exception("Unexpected secondary_channel (did not re-enable 40 MHz)")
  726. def test_ap_ht_40mhz_intolerant_ap(dev, apdev):
  727. """Associated STA reports 40 MHz intolerant AP after association"""
  728. clear_scan_cache(apdev[0]['ifname'])
  729. params = { "ssid": "ht",
  730. "channel": "6",
  731. "ht_capab": "[HT40-]",
  732. "obss_interval": "3" }
  733. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  734. dev[0].connect("ht", key_mgmt="NONE", scan_freq="2437")
  735. if hapd.get_status_field("secondary_channel") != "-1":
  736. raise Exception("Unexpected secondary channel information")
  737. logger.info("Start 40 MHz intolerant AP")
  738. params = { "ssid": "intolerant",
  739. "channel": "5",
  740. "ht_capab": "[40-INTOLERANT]" }
  741. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  742. logger.info("Waiting for co-ex report from STA")
  743. ok = False
  744. for i in range(0, 20):
  745. time.sleep(1)
  746. if hapd.get_status_field("secondary_channel") == "0":
  747. logger.info("AP moved to 20 MHz channel")
  748. ok = True
  749. break
  750. if not ok:
  751. raise Exception("AP did not move to 20 MHz channel")
  752. if "OK" not in hapd2.request("DISABLE"):
  753. raise Exception("Failed to disable 40 MHz intolerant AP")
  754. # make sure the intolerant AP disappears from scan results more quickly
  755. dev[0].scan(type="ONLY", freq="2432", only_new=True)
  756. dev[0].scan(type="ONLY", freq="2432", only_new=True)
  757. dev[0].dump_monitor()
  758. logger.info("Waiting for AP to move back to 40 MHz channel")
  759. ok = False
  760. for i in range(0, 30):
  761. time.sleep(1)
  762. if hapd.get_status_field("secondary_channel") == "-1":
  763. logger.info("AP moved to 40 MHz channel")
  764. ok = True
  765. break
  766. if not ok:
  767. raise Exception("AP did not move to 40 MHz channel")
  768. def test_ap_ht40_csa(dev, apdev):
  769. """HT with 40 MHz channel width and CSA"""
  770. csa_supported(dev[0])
  771. try:
  772. hapd = None
  773. params = { "ssid": "ht",
  774. "country_code": "US",
  775. "hw_mode": "a",
  776. "channel": "36",
  777. "ht_capab": "[HT40+]",
  778. "ieee80211n": "1" }
  779. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  780. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  781. hwsim_utils.test_connectivity(dev[0], hapd)
  782. hapd.request("CHAN_SWITCH 5 5200 ht sec_channel_offset=-1 bandwidth=40")
  783. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  784. if ev is None:
  785. raise Exception("CSA finished event timed out")
  786. if "freq=5200" not in ev:
  787. raise Exception("Unexpected channel in CSA finished event")
  788. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  789. if ev is not None:
  790. raise Exception("Unexpected STA disconnection during CSA")
  791. hwsim_utils.test_connectivity(dev[0], hapd)
  792. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  793. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  794. if ev is None:
  795. raise Exception("CSA finished event timed out")
  796. if "freq=5180" not in ev:
  797. raise Exception("Unexpected channel in CSA finished event")
  798. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  799. if ev is not None:
  800. raise Exception("Unexpected STA disconnection during CSA")
  801. hwsim_utils.test_connectivity(dev[0], hapd)
  802. finally:
  803. dev[0].request("DISCONNECT")
  804. if hapd:
  805. hapd.request("DISABLE")
  806. subprocess.call(['iw', 'reg', 'set', '00'])
  807. dev[0].flush_scan_cache()
  808. def test_ap_ht40_csa2(dev, apdev):
  809. """HT with 40 MHz channel width and CSA"""
  810. csa_supported(dev[0])
  811. try:
  812. hapd = None
  813. params = { "ssid": "ht",
  814. "country_code": "US",
  815. "hw_mode": "a",
  816. "channel": "36",
  817. "ht_capab": "[HT40+]",
  818. "ieee80211n": "1" }
  819. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  820. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  821. hwsim_utils.test_connectivity(dev[0], hapd)
  822. hapd.request("CHAN_SWITCH 5 5220 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=5220" 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. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  833. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  834. if ev is None:
  835. raise Exception("CSA finished event timed out")
  836. if "freq=5180" not in ev:
  837. raise Exception("Unexpected channel in CSA finished event")
  838. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  839. if ev is not None:
  840. raise Exception("Unexpected STA disconnection during CSA")
  841. hwsim_utils.test_connectivity(dev[0], hapd)
  842. finally:
  843. dev[0].request("DISCONNECT")
  844. if hapd:
  845. hapd.request("DISABLE")
  846. subprocess.call(['iw', 'reg', 'set', '00'])
  847. dev[0].flush_scan_cache()
  848. def test_ap_ht40_csa3(dev, apdev):
  849. """HT with 40 MHz channel width and CSA"""
  850. csa_supported(dev[0])
  851. try:
  852. hapd = None
  853. params = { "ssid": "ht",
  854. "country_code": "US",
  855. "hw_mode": "a",
  856. "channel": "36",
  857. "ht_capab": "[HT40+]",
  858. "ieee80211n": "1" }
  859. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  860. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  861. hwsim_utils.test_connectivity(dev[0], hapd)
  862. hapd.request("CHAN_SWITCH 5 5240 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=5240" 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. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  873. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  874. if ev is None:
  875. raise Exception("CSA finished event timed out")
  876. if "freq=5180" not in ev:
  877. raise Exception("Unexpected channel in CSA finished event")
  878. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  879. if ev is not None:
  880. raise Exception("Unexpected STA disconnection during CSA")
  881. hwsim_utils.test_connectivity(dev[0], hapd)
  882. finally:
  883. dev[0].request("DISCONNECT")
  884. if hapd:
  885. hapd.request("DISABLE")
  886. subprocess.call(['iw', 'reg', 'set', '00'])
  887. dev[0].flush_scan_cache()
  888. def test_ap_ht_smps(dev, apdev):
  889. """SMPS AP configuration options"""
  890. params = { "ssid": "ht1", "ht_capab": "[SMPS-STATIC]" }
  891. try:
  892. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  893. except:
  894. raise HwsimSkip("Assume mac80211_hwsim was not recent enough to support SMPS")
  895. params = { "ssid": "ht2", "ht_capab": "[SMPS-DYNAMIC]" }
  896. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  897. dev[0].connect("ht1", key_mgmt="NONE", scan_freq="2412")
  898. dev[1].connect("ht2", key_mgmt="NONE", scan_freq="2412")
  899. hwsim_utils.test_connectivity(dev[0], hapd)
  900. hwsim_utils.test_connectivity(dev[1], hapd2)
  901. def test_prefer_ht20(dev, apdev):
  902. """Preference on HT20 over no-HT"""
  903. params = { "ssid": "test",
  904. "channel": "1",
  905. "ieee80211n": "0" }
  906. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  907. bssid = apdev[0]['bssid']
  908. params = { "ssid": "test",
  909. "channel": "1",
  910. "ieee80211n": "1" }
  911. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  912. bssid2 = apdev[1]['bssid']
  913. dev[0].scan_for_bss(bssid, freq=2412)
  914. dev[0].scan_for_bss(bssid2, freq=2412)
  915. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  916. if dev[0].get_status_field('bssid') != bssid2:
  917. raise Exception("Unexpected BSS selected")
  918. est = dev[0].get_bss(bssid)['est_throughput']
  919. if est != "54000":
  920. raise Exception("Unexpected BSS0 est_throughput: " + est)
  921. est = dev[0].get_bss(bssid2)['est_throughput']
  922. if est != "65000":
  923. raise Exception("Unexpected BSS1 est_throughput: " + est)
  924. def test_prefer_ht40(dev, apdev):
  925. """Preference on HT40 over HT20"""
  926. params = { "ssid": "test",
  927. "channel": "1",
  928. "ieee80211n": "1" }
  929. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  930. bssid = apdev[0]['bssid']
  931. params = { "ssid": "test",
  932. "channel": "1",
  933. "ieee80211n": "1",
  934. "ht_capab": "[HT40+]" }
  935. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  936. bssid2 = apdev[1]['bssid']
  937. dev[0].scan_for_bss(bssid, freq=2412)
  938. dev[0].scan_for_bss(bssid2, freq=2412)
  939. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  940. if dev[0].get_status_field('bssid') != bssid2:
  941. raise Exception("Unexpected BSS selected")
  942. est = dev[0].get_bss(bssid)['est_throughput']
  943. if est != "65000":
  944. raise Exception("Unexpected BSS0 est_throughput: " + est)
  945. est = dev[0].get_bss(bssid2)['est_throughput']
  946. if est != "135000":
  947. raise Exception("Unexpected BSS1 est_throughput: " + est)
  948. def test_prefer_ht20_during_roam(dev, apdev):
  949. """Preference on HT20 over no-HT in roaming consideration"""
  950. params = { "ssid": "test",
  951. "channel": "1",
  952. "ieee80211n": "0" }
  953. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  954. bssid = apdev[0]['bssid']
  955. dev[0].scan_for_bss(bssid, freq=2412)
  956. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  957. params = { "ssid": "test",
  958. "channel": "1",
  959. "ieee80211n": "1" }
  960. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  961. bssid2 = apdev[1]['bssid']
  962. dev[0].scan_for_bss(bssid2, freq=2412)
  963. dev[0].scan(freq=2412)
  964. dev[0].wait_connected()
  965. if dev[0].get_status_field('bssid') != bssid2:
  966. raise Exception("Unexpected BSS selected")
  967. def test_ap_ht40_5ghz_invalid_pair(dev, apdev):
  968. """HT40 on 5 GHz with invalid channel pair"""
  969. clear_scan_cache(apdev[0]['ifname'])
  970. try:
  971. params = { "ssid": "test-ht40",
  972. "hw_mode": "a",
  973. "channel": "40",
  974. "country_code": "US",
  975. "ht_capab": "[HT40+]"}
  976. hapd = hostapd.add_ap(apdev[1]['ifname'], params, wait_enabled=False)
  977. ev = hapd.wait_event(["AP-DISABLED"], timeout=10)
  978. if not ev:
  979. raise Exception("AP setup failure timed out")
  980. finally:
  981. subprocess.call(['iw', 'reg', 'set', '00'])