test_ap_ht.py 45 KB

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