test_ap_ht.py 44 KB

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