test_ap_ht.py 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220
  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. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  457. hapd.set("ext_mgmt_frame_handling", "1")
  458. logger.info("Waiting for OBSS scan to occur")
  459. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
  460. if ev is None:
  461. raise Exception("Timed out while waiting for OBSS scan to start")
  462. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
  463. if ev is None:
  464. raise Exception("Timed out while waiting for OBSS scan results")
  465. received = False
  466. for i in range(0, 4):
  467. frame = hapd.mgmt_rx(timeout=5)
  468. if frame is None:
  469. raise Exception("MGMT RX wait timed out")
  470. if frame['subtype'] != 13:
  471. continue
  472. payload = frame['payload']
  473. if len(payload) < 3:
  474. continue
  475. (category, action, ie) = struct.unpack('BBB', payload[0:3])
  476. if category != 4:
  477. continue
  478. if action != 0:
  479. continue
  480. if ie == 72:
  481. logger.info("20/40 BSS Coexistence report received")
  482. received = True
  483. break
  484. if not received:
  485. raise Exception("20/40 BSS Coexistence report not seen")
  486. def test_obss_scan_40_intolerant(dev, apdev):
  487. """Overlapping BSS scan request with 40 MHz intolerant AP"""
  488. params = { "ssid": "obss-scan",
  489. "channel": "6",
  490. "ht_capab": "[HT40-]",
  491. "obss_interval": "10" }
  492. hapd = hostapd.add_ap(apdev[0], params)
  493. params = { "ssid": "another-bss",
  494. "channel": "7",
  495. "ht_capab": "[40-INTOLERANT]" }
  496. hostapd.add_ap(apdev[1], params)
  497. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  498. hapd.set("ext_mgmt_frame_handling", "1")
  499. logger.info("Waiting for OBSS scan to occur")
  500. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
  501. if ev is None:
  502. raise Exception("Timed out while waiting for OBSS scan to start")
  503. ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
  504. if ev is None:
  505. raise Exception("Timed out while waiting for OBSS scan results")
  506. received = False
  507. for i in range(0, 4):
  508. frame = hapd.mgmt_rx(timeout=5)
  509. if frame is None:
  510. raise Exception("MGMT RX wait timed out")
  511. if frame['subtype'] != 13:
  512. continue
  513. payload = frame['payload']
  514. if len(payload) < 3:
  515. continue
  516. (category, action, ie) = struct.unpack('BBB', payload[0:3])
  517. if category != 4:
  518. continue
  519. if action != 0:
  520. continue
  521. if ie == 72:
  522. logger.info("20/40 BSS Coexistence report received")
  523. received = True
  524. break
  525. if not received:
  526. raise Exception("20/40 BSS Coexistence report not seen")
  527. def test_obss_coex_report_handling(dev, apdev):
  528. """Overlapping BSS scan report handling with obss_interval=0"""
  529. clear_scan_cache(apdev[0])
  530. params = { "ssid": "obss-scan",
  531. "channel": "6",
  532. "ht_capab": "[HT40-]" }
  533. hapd = hostapd.add_ap(apdev[0], params)
  534. bssid = apdev[0]['bssid']
  535. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  536. sec = hapd.get_status_field("secondary_channel")
  537. if sec != "-1":
  538. raise Exception("AP is not using 40 MHz channel")
  539. # 20/40 MHz co-ex report tests: number of invalid reports and a valid report
  540. # that forces 20 MHz channel.
  541. tests = [ '0400', '040048', '04004801', '0400480000', '0400490100',
  542. '040048ff0000', '04004801ff49ff00', '04004801004900',
  543. '0400480100490101', '0400480100490201ff',
  544. '040048010449020005' ]
  545. for msg in tests:
  546. req = "MGMT_TX {} {} freq=2437 action={}".format(bssid, bssid, msg)
  547. if "OK" not in dev[0].request(req):
  548. raise Exception("Could not send management frame")
  549. time.sleep(0.5)
  550. sec = hapd.get_status_field("secondary_channel")
  551. if sec != "0":
  552. raise Exception("AP did not move to 20 MHz channel")
  553. def test_obss_coex_report_handling1(dev, apdev):
  554. """Overlapping BSS scan report handling with obss_interval=1"""
  555. clear_scan_cache(apdev[0])
  556. params = { "ssid": "obss-scan",
  557. "channel": "6",
  558. "ht_capab": "[HT40+]",
  559. "obss_interval": "1" }
  560. hapd = hostapd.add_ap(apdev[0], params)
  561. bssid = apdev[0]['bssid']
  562. dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
  563. sec = hapd.get_status_field("secondary_channel")
  564. if sec != "1":
  565. raise Exception("AP is not using 40 MHz channel")
  566. # 20/40 MHz co-ex report forcing 20 MHz channel
  567. msg = '040048010449020005'
  568. req = "MGMT_TX {} {} freq=2437 action={}".format(bssid, bssid, msg)
  569. if "OK" not in dev[0].request(req):
  570. raise Exception("Could not send management frame")
  571. time.sleep(0.5)
  572. sec = hapd.get_status_field("secondary_channel")
  573. if sec != "0":
  574. raise Exception("AP did not move to 20 MHz channel")
  575. # No 20/40 MHz co-ex reports forcing 20 MHz channel during next interval
  576. for i in range(20):
  577. sec = hapd.get_status_field("secondary_channel")
  578. if sec == "1":
  579. break
  580. time.sleep(0.5)
  581. if sec != "1":
  582. raise Exception("AP did not return to 40 MHz channel")
  583. def test_olbc(dev, apdev):
  584. """OLBC detection"""
  585. params = { "ssid": "test-olbc",
  586. "channel": "6",
  587. "ht_capab": "[HT40-]",
  588. "ap_table_expiration_time": "2" }
  589. hapd = hostapd.add_ap(apdev[0], params)
  590. status = hapd.get_status()
  591. if status['olbc'] != '0' or status['olbc_ht'] != '0':
  592. raise Exception("Unexpected OLBC information")
  593. params = { "ssid": "olbc-ap",
  594. "hw_mode": "b",
  595. "channel": "6",
  596. "wmm_enabled": "0" }
  597. hostapd.add_ap(apdev[1], params)
  598. time.sleep(0.5)
  599. status = hapd.get_status()
  600. if status['olbc'] != '1' or status['olbc_ht'] != '1':
  601. raise Exception("Missing OLBC information")
  602. hostapd.remove_bss(apdev[1])
  603. logger.info("Waiting for OLBC state to time out")
  604. cleared = False
  605. for i in range(0, 15):
  606. time.sleep(1)
  607. status = hapd.get_status()
  608. if status['olbc'] == '0' and status['olbc_ht'] == '0':
  609. cleared = True
  610. break
  611. if not cleared:
  612. raise Exception("OLBC state did nto time out")
  613. def test_olbc_table_limit(dev, apdev):
  614. """OLBC AP table size limit"""
  615. ifname1 = apdev[0]['ifname']
  616. ifname2 = apdev[0]['ifname'] + '-2'
  617. ifname3 = apdev[0]['ifname'] + '-3'
  618. hostapd.add_bss(apdev[0], ifname1, 'bss-1.conf')
  619. hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf')
  620. hostapd.add_bss(apdev[0], ifname3, 'bss-3.conf')
  621. params = { "ssid": "test-olbc",
  622. "channel": "1",
  623. "ap_table_max_size": "2" }
  624. hapd = hostapd.add_ap(apdev[1], params)
  625. time.sleep(0.3)
  626. with alloc_fail(hapd, 1, "ap_list_process_beacon"):
  627. time.sleep(0.3)
  628. hapd.set("ap_table_max_size", "1")
  629. time.sleep(0.3)
  630. hapd.set("ap_table_max_size", "0")
  631. time.sleep(0.3)
  632. def test_olbc_5ghz(dev, apdev):
  633. """OLBC detection on 5 GHz"""
  634. try:
  635. hapd = None
  636. hapd2 = None
  637. params = { "ssid": "test-olbc",
  638. "country_code": "FI",
  639. "hw_mode": "a",
  640. "channel": "36",
  641. "ht_capab": "[HT40+]" }
  642. hapd = hostapd.add_ap(apdev[0], params)
  643. status = hapd.get_status()
  644. if status['olbc'] != '0' or status['olbc_ht'] != '0':
  645. raise Exception("Unexpected OLBC information")
  646. params = { "ssid": "olbc-ap",
  647. "country_code": "FI",
  648. "hw_mode": "a",
  649. "channel": "36",
  650. "ieee80211n": "0",
  651. "wmm_enabled": "0" }
  652. hapd2 = hostapd.add_ap(apdev[1], params)
  653. found = False
  654. for i in range(20):
  655. time.sleep(0.1)
  656. status = hapd.get_status()
  657. logger.debug('olbc_ht: ' + status['olbc_ht'])
  658. if status['olbc_ht'] == '1':
  659. found = True
  660. break
  661. if not found:
  662. raise Exception("Missing OLBC information")
  663. finally:
  664. if hapd:
  665. hapd.request("DISABLE")
  666. if hapd2:
  667. hapd2.request("DISABLE")
  668. set_world_reg(apdev[0], apdev[1], None)
  669. def test_ap_require_ht(dev, apdev):
  670. """Require HT"""
  671. params = { "ssid": "require-ht",
  672. "require_ht": "1" }
  673. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  674. dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  675. disable_ht="1", wait_connect=False)
  676. dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
  677. ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
  678. dev[1].request("DISCONNECT")
  679. if ev is None:
  680. raise Exception("Association rejection timed out")
  681. if "status_code=27" not in ev:
  682. raise Exception("Unexpected rejection status code")
  683. dev[2].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  684. ht_mcs="0x01 00 00 00 00 00 00 00 00 00",
  685. disable_max_amsdu="1", ampdu_factor="2",
  686. ampdu_density="1", disable_ht40="1", disable_sgi="1",
  687. disable_ldpc="1")
  688. @remote_compatible
  689. def test_ap_require_ht_limited_rates(dev, apdev):
  690. """Require HT with limited supported rates"""
  691. params = { "ssid": "require-ht",
  692. "supported_rates": "60 120 240 360 480 540",
  693. "require_ht": "1" }
  694. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  695. dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
  696. disable_ht="1", wait_connect=False)
  697. dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
  698. ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
  699. dev[1].request("DISCONNECT")
  700. if ev is None:
  701. raise Exception("Association rejection timed out")
  702. if "status_code=27" not in ev:
  703. raise Exception("Unexpected rejection status code")
  704. @remote_compatible
  705. def test_ap_ht_capab_not_supported(dev, apdev):
  706. """HT configuration with driver not supporting all ht_capab entries"""
  707. params = { "ssid": "test-ht40",
  708. "channel": "5",
  709. "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]"}
  710. hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
  711. if "FAIL" not in hapd.request("ENABLE"):
  712. raise Exception("Unexpected ENABLE success")
  713. def test_ap_ht_40mhz_intolerant_sta(dev, apdev):
  714. """Associated STA indicating 40 MHz intolerant"""
  715. clear_scan_cache(apdev[0])
  716. params = { "ssid": "intolerant",
  717. "channel": "6",
  718. "ht_capab": "[HT40-]" }
  719. hapd = hostapd.add_ap(apdev[0], params)
  720. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  721. raise Exception("Unexpected num_sta_ht40_intolerant value")
  722. if hapd.get_status_field("secondary_channel") != "-1":
  723. raise Exception("Unexpected secondary_channel")
  724. dev[0].connect("intolerant", key_mgmt="NONE", scan_freq="2437")
  725. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  726. raise Exception("Unexpected num_sta_ht40_intolerant value")
  727. if hapd.get_status_field("secondary_channel") != "-1":
  728. raise Exception("Unexpected secondary_channel")
  729. dev[2].connect("intolerant", key_mgmt="NONE", scan_freq="2437",
  730. ht40_intolerant="1")
  731. time.sleep(1)
  732. if hapd.get_status_field("num_sta_ht40_intolerant") != "1":
  733. raise Exception("Unexpected num_sta_ht40_intolerant value (expected 1)")
  734. if hapd.get_status_field("secondary_channel") != "0":
  735. raise Exception("Unexpected secondary_channel (did not disable 40 MHz)")
  736. dev[2].request("DISCONNECT")
  737. time.sleep(1)
  738. if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
  739. raise Exception("Unexpected num_sta_ht40_intolerant value (expected 0)")
  740. if hapd.get_status_field("secondary_channel") != "-1":
  741. raise Exception("Unexpected secondary_channel (did not re-enable 40 MHz)")
  742. def test_ap_ht_40mhz_intolerant_ap(dev, apdev):
  743. """Associated STA reports 40 MHz intolerant AP after association"""
  744. clear_scan_cache(apdev[0])
  745. params = { "ssid": "ht",
  746. "channel": "6",
  747. "ht_capab": "[HT40-]",
  748. "obss_interval": "3" }
  749. hapd = hostapd.add_ap(apdev[0], params)
  750. dev[0].connect("ht", key_mgmt="NONE", scan_freq="2437")
  751. if hapd.get_status_field("secondary_channel") != "-1":
  752. raise Exception("Unexpected secondary channel information")
  753. logger.info("Start 40 MHz intolerant AP")
  754. params = { "ssid": "intolerant",
  755. "channel": "5",
  756. "ht_capab": "[40-INTOLERANT]" }
  757. hapd2 = hostapd.add_ap(apdev[1], params)
  758. logger.info("Waiting for co-ex report from STA")
  759. ok = False
  760. for i in range(0, 20):
  761. time.sleep(1)
  762. if hapd.get_status_field("secondary_channel") == "0":
  763. logger.info("AP moved to 20 MHz channel")
  764. ok = True
  765. break
  766. if not ok:
  767. raise Exception("AP did not move to 20 MHz channel")
  768. if "OK" not in hapd2.request("DISABLE"):
  769. raise Exception("Failed to disable 40 MHz intolerant AP")
  770. # make sure the intolerant AP disappears from scan results more quickly
  771. dev[0].scan(type="ONLY", freq="2432", only_new=True)
  772. dev[0].scan(type="ONLY", freq="2432", only_new=True)
  773. dev[0].dump_monitor()
  774. logger.info("Waiting for AP to move back to 40 MHz channel")
  775. ok = False
  776. for i in range(0, 30):
  777. time.sleep(1)
  778. if hapd.get_status_field("secondary_channel") == "-1":
  779. logger.info("AP moved to 40 MHz channel")
  780. ok = True
  781. break
  782. if not ok:
  783. raise Exception("AP did not move to 40 MHz channel")
  784. def test_ap_ht40_csa(dev, apdev):
  785. """HT with 40 MHz channel width and CSA"""
  786. csa_supported(dev[0])
  787. try:
  788. hapd = None
  789. params = { "ssid": "ht",
  790. "country_code": "US",
  791. "hw_mode": "a",
  792. "channel": "36",
  793. "ht_capab": "[HT40+]",
  794. "ieee80211n": "1" }
  795. hapd = hostapd.add_ap(apdev[0], params)
  796. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  797. hwsim_utils.test_connectivity(dev[0], hapd)
  798. hapd.request("CHAN_SWITCH 5 5200 ht sec_channel_offset=-1 bandwidth=40")
  799. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  800. if ev is None:
  801. raise Exception("CSA finished event timed out")
  802. if "freq=5200" not in ev:
  803. raise Exception("Unexpected channel in CSA finished event")
  804. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  805. if ev is not None:
  806. raise Exception("Unexpected STA disconnection during CSA")
  807. hwsim_utils.test_connectivity(dev[0], hapd)
  808. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  809. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  810. if ev is None:
  811. raise Exception("CSA finished event timed out")
  812. if "freq=5180" not in ev:
  813. raise Exception("Unexpected channel in CSA finished event")
  814. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  815. if ev is not None:
  816. raise Exception("Unexpected STA disconnection during CSA")
  817. hwsim_utils.test_connectivity(dev[0], hapd)
  818. finally:
  819. dev[0].request("DISCONNECT")
  820. if hapd:
  821. hapd.request("DISABLE")
  822. set_world_reg(apdev[0], None, dev[0])
  823. dev[0].flush_scan_cache()
  824. def test_ap_ht40_csa2(dev, apdev):
  825. """HT with 40 MHz channel width and CSA"""
  826. csa_supported(dev[0])
  827. try:
  828. hapd = None
  829. params = { "ssid": "ht",
  830. "country_code": "US",
  831. "hw_mode": "a",
  832. "channel": "36",
  833. "ht_capab": "[HT40+]",
  834. "ieee80211n": "1" }
  835. hapd = hostapd.add_ap(apdev[0], params)
  836. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  837. hwsim_utils.test_connectivity(dev[0], hapd)
  838. hapd.request("CHAN_SWITCH 5 5220 ht sec_channel_offset=1 bandwidth=40")
  839. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  840. if ev is None:
  841. raise Exception("CSA finished event timed out")
  842. if "freq=5220" not in ev:
  843. raise Exception("Unexpected channel in CSA finished event")
  844. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  845. if ev is not None:
  846. raise Exception("Unexpected STA disconnection during CSA")
  847. hwsim_utils.test_connectivity(dev[0], hapd)
  848. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  849. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  850. if ev is None:
  851. raise Exception("CSA finished event timed out")
  852. if "freq=5180" not in ev:
  853. raise Exception("Unexpected channel in CSA finished event")
  854. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  855. if ev is not None:
  856. raise Exception("Unexpected STA disconnection during CSA")
  857. hwsim_utils.test_connectivity(dev[0], hapd)
  858. finally:
  859. dev[0].request("DISCONNECT")
  860. if hapd:
  861. hapd.request("DISABLE")
  862. set_world_reg(apdev[0], None, dev[0])
  863. dev[0].flush_scan_cache()
  864. def test_ap_ht40_csa3(dev, apdev):
  865. """HT with 40 MHz channel width and CSA"""
  866. csa_supported(dev[0])
  867. try:
  868. hapd = None
  869. params = { "ssid": "ht",
  870. "country_code": "US",
  871. "hw_mode": "a",
  872. "channel": "36",
  873. "ht_capab": "[HT40+]",
  874. "ieee80211n": "1" }
  875. hapd = hostapd.add_ap(apdev[0], params)
  876. dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
  877. hwsim_utils.test_connectivity(dev[0], hapd)
  878. hapd.request("CHAN_SWITCH 5 5240 ht sec_channel_offset=-1 bandwidth=40")
  879. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  880. if ev is None:
  881. raise Exception("CSA finished event timed out")
  882. if "freq=5240" not in ev:
  883. raise Exception("Unexpected channel in CSA finished event")
  884. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  885. if ev is not None:
  886. raise Exception("Unexpected STA disconnection during CSA")
  887. hwsim_utils.test_connectivity(dev[0], hapd)
  888. hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
  889. ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
  890. if ev is None:
  891. raise Exception("CSA finished event timed out")
  892. if "freq=5180" not in ev:
  893. raise Exception("Unexpected channel in CSA finished event")
  894. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
  895. if ev is not None:
  896. raise Exception("Unexpected STA disconnection during CSA")
  897. hwsim_utils.test_connectivity(dev[0], hapd)
  898. finally:
  899. dev[0].request("DISCONNECT")
  900. if hapd:
  901. hapd.request("DISABLE")
  902. set_world_reg(apdev[0], None, dev[0])
  903. dev[0].flush_scan_cache()
  904. @remote_compatible
  905. def test_ap_ht_smps(dev, apdev):
  906. """SMPS AP configuration options"""
  907. params = { "ssid": "ht1", "ht_capab": "[SMPS-STATIC]" }
  908. try:
  909. hapd = hostapd.add_ap(apdev[0], params)
  910. except:
  911. raise HwsimSkip("Assume mac80211_hwsim was not recent enough to support SMPS")
  912. params = { "ssid": "ht2", "ht_capab": "[SMPS-DYNAMIC]" }
  913. hapd2 = hostapd.add_ap(apdev[1], params)
  914. dev[0].connect("ht1", key_mgmt="NONE", scan_freq="2412")
  915. dev[1].connect("ht2", key_mgmt="NONE", scan_freq="2412")
  916. hwsim_utils.test_connectivity(dev[0], hapd)
  917. hwsim_utils.test_connectivity(dev[1], hapd2)
  918. @remote_compatible
  919. def test_prefer_ht20(dev, apdev):
  920. """Preference on HT20 over no-HT"""
  921. params = { "ssid": "test",
  922. "channel": "1",
  923. "ieee80211n": "0" }
  924. hapd = hostapd.add_ap(apdev[0], params)
  925. bssid = apdev[0]['bssid']
  926. params = { "ssid": "test",
  927. "channel": "1",
  928. "ieee80211n": "1" }
  929. hapd2 = hostapd.add_ap(apdev[1], params)
  930. bssid2 = apdev[1]['bssid']
  931. dev[0].scan_for_bss(bssid, freq=2412)
  932. dev[0].scan_for_bss(bssid2, freq=2412)
  933. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  934. if dev[0].get_status_field('bssid') != bssid2:
  935. raise Exception("Unexpected BSS selected")
  936. est = dev[0].get_bss(bssid)['est_throughput']
  937. if est != "54000":
  938. raise Exception("Unexpected BSS0 est_throughput: " + est)
  939. est = dev[0].get_bss(bssid2)['est_throughput']
  940. if est != "65000":
  941. raise Exception("Unexpected BSS1 est_throughput: " + est)
  942. def test_prefer_ht40(dev, apdev):
  943. """Preference on HT40 over HT20"""
  944. params = { "ssid": "test",
  945. "channel": "1",
  946. "ieee80211n": "1" }
  947. hapd = hostapd.add_ap(apdev[0], params)
  948. bssid = apdev[0]['bssid']
  949. params = { "ssid": "test",
  950. "channel": "1",
  951. "ieee80211n": "1",
  952. "ht_capab": "[HT40+]" }
  953. hapd2 = hostapd.add_ap(apdev[1], params)
  954. bssid2 = apdev[1]['bssid']
  955. dev[0].scan_for_bss(bssid, freq=2412)
  956. dev[0].scan_for_bss(bssid2, freq=2412)
  957. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  958. if dev[0].get_status_field('bssid') != bssid2:
  959. raise Exception("Unexpected BSS selected")
  960. est = dev[0].get_bss(bssid)['est_throughput']
  961. if est != "65000":
  962. raise Exception("Unexpected BSS0 est_throughput: " + est)
  963. est = dev[0].get_bss(bssid2)['est_throughput']
  964. if est != "135000":
  965. raise Exception("Unexpected BSS1 est_throughput: " + est)
  966. @remote_compatible
  967. def test_prefer_ht20_during_roam(dev, apdev):
  968. """Preference on HT20 over no-HT in roaming consideration"""
  969. params = { "ssid": "test",
  970. "channel": "1",
  971. "ieee80211n": "0" }
  972. hapd = hostapd.add_ap(apdev[0], params)
  973. bssid = apdev[0]['bssid']
  974. dev[0].scan_for_bss(bssid, freq=2412)
  975. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  976. params = { "ssid": "test",
  977. "channel": "1",
  978. "ieee80211n": "1" }
  979. hapd2 = hostapd.add_ap(apdev[1], params)
  980. bssid2 = apdev[1]['bssid']
  981. dev[0].scan_for_bss(bssid2, freq=2412)
  982. dev[0].scan(freq=2412)
  983. dev[0].wait_connected()
  984. if dev[0].get_status_field('bssid') != bssid2:
  985. raise Exception("Unexpected BSS selected")
  986. @remote_compatible
  987. def test_ap_ht40_5ghz_invalid_pair(dev, apdev):
  988. """HT40 on 5 GHz with invalid channel pair"""
  989. clear_scan_cache(apdev[0])
  990. try:
  991. params = { "ssid": "test-ht40",
  992. "hw_mode": "a",
  993. "channel": "40",
  994. "country_code": "US",
  995. "ht_capab": "[HT40+]"}
  996. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  997. ev = hapd.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout=10)
  998. if not ev:
  999. raise Exception("AP setup failure timed out")
  1000. if "AP-ENABLED" in ev:
  1001. sec = hapd.get_status_field("secondary_channel")
  1002. if sec != "0":
  1003. raise Exception("Invalid 40 MHz channel accepted")
  1004. finally:
  1005. set_world_reg(apdev[0], None, None)
  1006. @remote_compatible
  1007. def test_ap_ht40_5ghz_disabled_sec(dev, apdev):
  1008. """HT40 on 5 GHz with disabled secondary channel"""
  1009. clear_scan_cache(apdev[0])
  1010. try:
  1011. params = { "ssid": "test-ht40",
  1012. "hw_mode": "a",
  1013. "channel": "48",
  1014. "country_code": "US",
  1015. "ht_capab": "[HT40+]"}
  1016. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  1017. ev = hapd.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout=10)
  1018. if not ev:
  1019. raise Exception("AP setup failure timed out")
  1020. if "AP-ENABLED" in ev:
  1021. sec = hapd.get_status_field("secondary_channel")
  1022. if sec != "0":
  1023. raise Exception("Invalid 40 MHz channel accepted")
  1024. finally:
  1025. set_world_reg(apdev[0], None, None)
  1026. def test_ap_ht40_scan_broken_ap(dev, apdev):
  1027. """HT40 co-ex scan and broken legacy/HT AP"""
  1028. clear_scan_cache(apdev[0])
  1029. # Broken AP: Include HT Capabilities element but not HT Operation element
  1030. params = { "ssid": "legacy-20",
  1031. "channel": "7", "ieee80211n": "0",
  1032. "wmm_enabled": "1",
  1033. "vendor_elements": "2d1a0e001bffff000000000000000000000100000000000000000000" }
  1034. hapd2 = hostapd.add_ap(apdev[1], params)
  1035. params = { "ssid": "test-ht40",
  1036. "channel": "5",
  1037. "ht_capab": "[HT40-]"}
  1038. hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
  1039. state = hapd.get_status_field("state")
  1040. if state != "HT_SCAN":
  1041. time.sleep(0.1)
  1042. state = hapd.get_status_field("state")
  1043. if state != "HT_SCAN":
  1044. raise Exception("Unexpected interface state - expected HT_SCAN")
  1045. ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
  1046. if not ev:
  1047. raise Exception("AP setup timed out")
  1048. state = hapd.get_status_field("state")
  1049. if state != "ENABLED":
  1050. raise Exception("Unexpected interface state - expected ENABLED")
  1051. freq = hapd.get_status_field("freq")
  1052. if freq != "2432":
  1053. raise Exception("Unexpected frequency: " + freq)
  1054. pri = hapd.get_status_field("channel")
  1055. if pri != "5":
  1056. raise Exception("Unexpected primary channel: " + pri)
  1057. sec = hapd.get_status_field("secondary_channel")
  1058. if sec != "-1":
  1059. raise Exception("Unexpected secondary channel: " + sec)
  1060. dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
  1061. dev[1].connect("legacy-20", key_mgmt="NONE", scan_freq="2442")
  1062. hwsim_utils.test_connectivity(dev[0], hapd)
  1063. hwsim_utils.test_connectivity(dev[1], hapd2)