test_wpas_wmm_ac.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. # Test cases for wpa_supplicant WMM-AC operations
  2. # Copyright (c) 2014, Intel Corporation
  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 logging
  8. logger = logging.getLogger()
  9. import struct
  10. import hwsim_utils
  11. import hostapd
  12. def add_wmm_ap(apdev, acm_list):
  13. params = { "ssid": "wmm_ac",
  14. "hw_mode": "g",
  15. "channel": "11",
  16. "wmm_enabled" : "1"}
  17. for ac in acm_list:
  18. params["wmm_ac_%s_acm" % (ac.lower())] = "1"
  19. return hostapd.add_ap(apdev, params)
  20. def test_tspec(dev, apdev):
  21. """Basic addts/delts tests"""
  22. # configure ap with VO and VI requiring admission-control
  23. hapd = add_wmm_ap(apdev[0], ["VO", "VI"])
  24. dev[0].connect("wmm_ac", key_mgmt="NONE", scan_freq="2462")
  25. hwsim_utils.test_connectivity(dev[0], hapd)
  26. status = dev[0].request("WMM_AC_STATUS")
  27. if "WMM AC is Enabled" not in status:
  28. raise Exception("WMM-AC not enabled")
  29. if "TSID" in status:
  30. raise Exception("Unexpected TSID info")
  31. if "BK: acm=0 uapsd=0" not in status:
  32. raise Exception("Unexpected BK info" + status)
  33. if "BE: acm=0 uapsd=0" not in status:
  34. raise Exception("Unexpected BE info" + status)
  35. if "VI: acm=1 uapsd=0" not in status:
  36. raise Exception("Unexpected VI info" + status)
  37. if "VO: acm=1 uapsd=0" not in status:
  38. raise Exception("Unexpected VO info" + status)
  39. # no tsid --> tsid out of range
  40. if "FAIL" not in dev[0].request("WMM_AC_ADDTS downlink"):
  41. raise Exception("Invalid WMM_AC_ADDTS accepted")
  42. # no direction
  43. if "FAIL" not in dev[0].request("WMM_AC_ADDTS tsid=5"):
  44. raise Exception("Invalid WMM_AC_ADDTS accepted")
  45. # param out of range
  46. if "FAIL" not in dev[0].request("WMM_AC_ADDTS tsid=5 downlink"):
  47. raise Exception("Invalid WMM_AC_ADDTS accepted")
  48. tsid = 5
  49. # make sure we fail when the ac is not configured for acm
  50. try:
  51. dev[0].add_ts(tsid, 3)
  52. raise Exception("ADDTS succeeded although it should have failed")
  53. except Exception, e:
  54. if not str(e).startswith("ADDTS failed"):
  55. raise
  56. status = dev[0].request("WMM_AC_STATUS")
  57. if "TSID" in status:
  58. raise Exception("Unexpected TSID info")
  59. # add tspec for UP=6
  60. dev[0].add_ts(tsid, 6)
  61. status = dev[0].request("WMM_AC_STATUS")
  62. if "TSID" not in status:
  63. raise Exception("Missing TSID info")
  64. # using the same tsid for a different ac is invalid
  65. try:
  66. dev[0].add_ts(tsid, 5)
  67. raise Exception("ADDTS succeeded although it should have failed")
  68. except Exception, e:
  69. if not str(e).startswith("ADDTS failed"):
  70. raise
  71. # update the tspec for a different UP of the same ac
  72. dev[0].add_ts(tsid, 7, extra="fixed_nominal_msdu")
  73. dev[0].del_ts(tsid)
  74. status = dev[0].request("WMM_AC_STATUS")
  75. if "TSID" in status:
  76. raise Exception("Unexpected TSID info")
  77. # verify failure on uplink/bidi without driver support
  78. tsid = 6
  79. try:
  80. dev[0].add_ts(tsid, 7, direction="uplink")
  81. raise Exception("ADDTS succeeded although it should have failed")
  82. except Exception, e:
  83. if not str(e).startswith("ADDTS failed"):
  84. raise
  85. try:
  86. dev[0].add_ts(tsid, 7, direction="bidi")
  87. raise Exception("ADDTS succeeded although it should have failed")
  88. except Exception, e:
  89. if not str(e).startswith("ADDTS failed"):
  90. raise
  91. # attempt to delete non-existing tsid
  92. try:
  93. dev[0].del_ts(tsid)
  94. raise Exception("DELTS succeeded although it should have failed")
  95. except Exception, e:
  96. if not str(e).startswith("DELTS failed"):
  97. raise
  98. def test_tspec_protocol(dev, apdev):
  99. """Protocol tests for addts/delts"""
  100. # configure ap with VO and VI requiring admission-control
  101. hapd = add_wmm_ap(apdev[0], ["VO", "VI"])
  102. dev[0].connect("wmm_ac", key_mgmt="NONE", scan_freq="2462")
  103. dev[0].dump_monitor()
  104. hapd.set("ext_mgmt_frame_handling", "1")
  105. tsid = 6
  106. # timeout on ADDTS response
  107. dev[0].add_ts(tsid, 7, expect_failure=True)
  108. hapd.dump_monitor()
  109. req = "WMM_AC_ADDTS downlink tsid=6 up=7 nominal_msdu_size=1500 sba=9000 mean_data_rate=1500 min_phy_rate=6000000"
  110. if "OK" not in dev[0].request(req):
  111. raise Exception("WMM_AC_ADDTS failed")
  112. # a new request while previous is still pending
  113. if "FAIL" not in dev[0].request(req):
  114. raise Exception("WMM_AC_ADDTS accepted while oen was still pending")
  115. msg = hapd.mgmt_rx()
  116. payload = msg['payload']
  117. (categ, action, dialog, status) = struct.unpack('BBBB', payload[0:4])
  118. if action != 0:
  119. raise Exception("Unexpected Action code: %d" % action)
  120. msg['da'] = msg['sa']
  121. msg['sa'] = apdev[0]['bssid']
  122. # unexpected dialog token
  123. msg['payload'] = struct.pack('BBBB', 17, 1, (dialog + 1) & 0xff, 0) + payload[4:]
  124. hapd.mgmt_tx(msg)
  125. # valid response
  126. msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 0) + payload[4:]
  127. hapd.mgmt_tx(msg)
  128. ev = dev[0].wait_event(["TSPEC-ADDED"], timeout=10)
  129. if ev is None:
  130. raise Exception("Timeout on TSPEC-ADDED")
  131. if "tsid=%d" % tsid not in ev:
  132. raise Exception("Unexpected TSPEC-ADDED contents: " + ev)
  133. # duplicated response
  134. msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 0) + payload[4:]
  135. hapd.mgmt_tx(msg)
  136. # too short ADDTS
  137. msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 0)
  138. hapd.mgmt_tx(msg)
  139. # invalid IE
  140. msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 0) + payload[4:] + struct.pack('BB', 0xdd, 100)
  141. hapd.mgmt_tx(msg)
  142. # too short WMM element
  143. msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 0) + payload[4:] + '\xdd\x06\x00\x50\xf2\x02\x02\x01'
  144. hapd.mgmt_tx(msg)
  145. # DELTS
  146. dev[0].dump_monitor()
  147. msg['payload'] = struct.pack('BBBB', 17, 2, 0, 0) + payload[4:]
  148. hapd.mgmt_tx(msg)
  149. ev = dev[0].wait_event(['TSPEC-REMOVED'], timeout=6)
  150. if ev is None:
  151. raise Exception("Timeout on TSPEC-REMOVED event")
  152. if "tsid=%d" % tsid not in ev:
  153. raise Exception("Unexpected TSPEC-REMOVED contents: " + ev)
  154. # DELTS duplicated
  155. msg['payload'] = struct.pack('BBBB', 17, 2, 0, 0) + payload[4:]
  156. hapd.mgmt_tx(msg)
  157. # start a new request
  158. hapd.dump_monitor()
  159. if "OK" not in dev[0].request(req):
  160. raise Exception("WMM_AC_ADDTS failed")
  161. msg = hapd.mgmt_rx()
  162. payload = msg['payload']
  163. (categ, action, dialog, status) = struct.unpack('BBBB', payload[0:4])
  164. if action != 0:
  165. raise Exception("Unexpected Action code: %d" % action)
  166. msg['da'] = msg['sa']
  167. msg['sa'] = apdev[0]['bssid']
  168. # modified parameters
  169. msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 1) + payload[4:12] + struct.pack('B', ord(payload[12]) & ~0x60) + payload[13:]
  170. hapd.mgmt_tx(msg)
  171. # reject request
  172. msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 1) + payload[4:]
  173. hapd.mgmt_tx(msg)
  174. ev = dev[0].wait_event(["TSPEC-REQ-FAILED"], timeout=10)
  175. if ev is None:
  176. raise Exception("Timeout on TSPEC-REQ-FAILED")
  177. if "tsid=%d" % tsid not in ev:
  178. raise Exception("Unexpected TSPEC-REQ-FAILED contents: " + ev)
  179. hapd.set("ext_mgmt_frame_handling", "0")
  180. @remote_compatible
  181. def test_tspec_not_enabled(dev, apdev):
  182. """addts failing if AP does not support WMM"""
  183. params = { "ssid": "wmm_no_ac",
  184. "hw_mode": "g",
  185. "channel": "11",
  186. "wmm_enabled" : "0" }
  187. hapd = hostapd.add_ap(apdev[0], params)
  188. dev[0].connect("wmm_no_ac", key_mgmt="NONE", scan_freq="2462")
  189. status = dev[0].request("WMM_AC_STATUS")
  190. if "Not associated to a WMM AP, WMM AC is Disabled" not in status:
  191. raise Exception("Unexpected WMM_AC_STATUS: " + status)
  192. try:
  193. dev[0].add_ts(5, 6)
  194. raise Exception("ADDTS succeeded although it should have failed")
  195. except Exception, e:
  196. if not str(e).startswith("ADDTS failed"):
  197. raise
  198. # attempt to delete non-existing tsid
  199. try:
  200. dev[0].del_ts(5)
  201. raise Exception("DELTS succeeded although it should have failed")
  202. except Exception, e:
  203. if not str(e).startswith("DELTS failed"):
  204. raise
  205. # unexpected Action frame when WMM is disabled
  206. MGMT_SUBTYPE_ACTION = 13
  207. msg = {}
  208. msg['fc'] = MGMT_SUBTYPE_ACTION << 4
  209. msg['da'] = dev[0].p2p_interface_addr()
  210. msg['sa'] = apdev[0]['bssid']
  211. msg['bssid'] = apdev[0]['bssid']
  212. msg['payload'] = struct.pack('BBBB', 17, 2, 0, 0)
  213. hapd.mgmt_tx(msg)
  214. @remote_compatible
  215. def test_tspec_ap_roam_open(dev, apdev):
  216. """Roam between two open APs while having tspecs"""
  217. hapd0 = add_wmm_ap(apdev[0], ["VO", "VI"])
  218. dev[0].connect("wmm_ac", key_mgmt="NONE")
  219. hwsim_utils.test_connectivity(dev[0], hapd0)
  220. dev[0].add_ts(5, 6)
  221. hapd1 = add_wmm_ap(apdev[1], ["VO", "VI"])
  222. dev[0].scan_for_bss(apdev[1]['bssid'], freq=2462)
  223. dev[0].roam(apdev[1]['bssid'])
  224. hwsim_utils.test_connectivity(dev[0], hapd1)
  225. if dev[0].tspecs():
  226. raise Exception("TSPECs weren't deleted on roaming")
  227. dev[0].scan_for_bss(apdev[0]['bssid'], freq=2462)
  228. dev[0].roam(apdev[0]['bssid'])
  229. hwsim_utils.test_connectivity(dev[0], hapd0)
  230. @remote_compatible
  231. def test_tspec_reassoc(dev, apdev):
  232. """Reassociation to same BSS while having tspecs"""
  233. hapd0 = add_wmm_ap(apdev[0], ["VO", "VI"])
  234. dev[0].connect("wmm_ac", key_mgmt="NONE")
  235. hwsim_utils.test_connectivity(dev[0], hapd0)
  236. dev[0].add_ts(5, 6)
  237. last_tspecs = dev[0].tspecs()
  238. dev[0].request("REASSOCIATE")
  239. dev[0].wait_connected()
  240. hwsim_utils.test_connectivity(dev[0], hapd0)
  241. if dev[0].tspecs() != last_tspecs:
  242. raise Exception("TSPECs weren't saved on reassociation")