test_rrm.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. # Radio measurement
  2. # Copyright(c) 2013 - 2016 Intel Mobile Communications GmbH.
  3. # Copyright(c) 2011 - 2016 Intel Corporation. All rights reserved.
  4. #
  5. # This software may be distributed under the terms of the BSD license.
  6. # See README for more details.
  7. import re
  8. import logging
  9. logger = logging.getLogger()
  10. import hostapd
  11. from utils import HwsimSkip
  12. nr="00112233445500000000510107"
  13. lci="01000800101298c0b512926666f6c2f1001c00004104050000c00012"
  14. civic="01000b0011223344556677889900998877665544332211aabbccddeeff"
  15. def check_nr_results(dev, bssids=None, lci=False, civic=False):
  16. if bssids is None:
  17. ev = dev.wait_event(["RRM-NEIGHBOR-REP-REQUEST-FAILED" ], timeout=10)
  18. if ev is None:
  19. raise Exception("RRM neighbor report failure not received")
  20. return
  21. received = []
  22. for bssid in bssids:
  23. ev = dev.wait_event(["RRM-NEIGHBOR-REP-RECEIVED"], timeout=10)
  24. if ev is None:
  25. raise Exception("RRM report result not indicated")
  26. received.append(ev)
  27. for bssid in bssids:
  28. found = False
  29. for r in received:
  30. if "RRM-NEIGHBOR-REP-RECEIVED bssid=" + bssid in r:
  31. if lci and "lci=" not in r:
  32. raise Exception("LCI data not reported for %s" % bssid)
  33. if civic and "civic=" not in r:
  34. raise Exception("civic data not reported for %s" % bssid)
  35. received.remove(r)
  36. found = True
  37. break
  38. if not found:
  39. raise Exception("RRM report result for %s not indicated" % bssid)
  40. def test_rrm_neighbor_db(dev, apdev):
  41. """hostapd ctrl_iface SET_NEIGHBOR"""
  42. params = { "ssid": "test", "rrm_neighbor_report": "1" }
  43. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  44. # Bad BSSID
  45. if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:gg ssid=\"test1\" nr=" + nr):
  46. raise Exception("Set neighbor succeeded unexpectedly")
  47. # Bad SSID
  48. if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=test1 nr=" + nr):
  49. raise Exception("Set neighbor succeeded unexpectedly")
  50. # No SSID
  51. if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 nr=" + nr):
  52. raise Exception("Set neighbor succeeded unexpectedly")
  53. # No NR
  54. if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\""):
  55. raise Exception("Set neighbor succeeded unexpectedly")
  56. # Odd length of NR
  57. if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr[:-1]):
  58. raise Exception("Set neighbor succeeded unexpectedly")
  59. # No entry yet in database
  60. if "FAIL" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\""):
  61. raise Exception("Remove neighbor succeeded unexpectedly")
  62. # Add a neighbor entry
  63. if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic):
  64. raise Exception("Set neighbor failed")
  65. # Another BSSID with the same SSID
  66. if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:56 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic):
  67. raise Exception("Set neighbor failed")
  68. # Fewer parameters
  69. if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr):
  70. raise Exception("Set neighbor failed")
  71. # SSID in hex format
  72. if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=7465737431 nr=" + nr):
  73. raise Exception("Set neighbor failed")
  74. # With more parameters
  75. if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " civic=" + civic):
  76. raise Exception("Set neighbor failed")
  77. # With all parameters
  78. if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic):
  79. raise Exception("Set neighbor failed")
  80. # Another SSID on the same BSSID
  81. if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test2\" nr=" + nr + " lci=" + lci):
  82. raise Exception("Set neighbor failed")
  83. if "OK" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\""):
  84. raise Exception("Remove neighbor failed")
  85. if "OK" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:56 ssid=\"test1\""):
  86. raise Exception("Remove neighbor failed")
  87. if "OK" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test2\""):
  88. raise Exception("Remove neighbor failed")
  89. # Double remove
  90. if "FAIL" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\""):
  91. raise Exception("Remove neighbor succeeded unexpectedly")
  92. def test_rrm_neighbor_rep_req(dev, apdev):
  93. """wpa_supplicant ctrl_iface NEIGHBOR_REP_REQUEST"""
  94. nr1="00112233445500000000510107"
  95. nr2="00112233445600000000510107"
  96. nr3="dd112233445500000000510107"
  97. params = { "ssid": "test" }
  98. hostapd.add_ap(apdev[0]['ifname'], params)
  99. params = { "ssid": "test2", "rrm_neighbor_report": "1" }
  100. hapd = hostapd.add_ap(apdev[1]['ifname'], params)
  101. bssid1 = apdev[1]['bssid']
  102. dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
  103. if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
  104. raise Exception("Request succeeded unexpectedly (AP without RRM)")
  105. if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"abcdef\""):
  106. raise Exception("Request succeeded unexpectedly (AP without RRM 2)")
  107. dev[0].request("DISCONNECT")
  108. rrm = int(dev[0].get_driver_status_field("capa.rrm_flags"), 16)
  109. if rrm & 0x5 != 0x5 and rrm & 0x10 != 0x10:
  110. raise HwsimSkip("Required RRM capabilities are not supported")
  111. dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
  112. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
  113. raise Exception("Request failed")
  114. check_nr_results(dev[0], [bssid1])
  115. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST lci"):
  116. raise Exception("Request failed")
  117. check_nr_results(dev[0], [bssid1])
  118. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST lci civic"):
  119. raise Exception("Request failed")
  120. check_nr_results(dev[0], [bssid1])
  121. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\""):
  122. raise Exception("Request failed")
  123. check_nr_results(dev[0])
  124. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\" lci civic"):
  125. raise Exception("Request failed")
  126. check_nr_results(dev[0])
  127. if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test3\" nr=" + nr1 + " lci=" + lci + " civic=" + civic):
  128. raise Exception("Set neighbor failed")
  129. if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:56 ssid=\"test3\" nr=" + nr2 + " lci=" + lci + " civic=" + civic):
  130. raise Exception("Set neighbor failed")
  131. if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:56 ssid=\"test4\" nr=" + nr2 + " lci=" + lci + " civic=" + civic):
  132. raise Exception("Set neighbor failed")
  133. if "OK" not in hapd.request("SET_NEIGHBOR dd:11:22:33:44:55 ssid=\"test5\" nr=" + nr3 + " lci=" + lci):
  134. raise Exception("Set neighbor failed")
  135. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\""):
  136. raise Exception("Request failed")
  137. check_nr_results(dev[0], ["00:11:22:33:44:55", "00:11:22:33:44:56"])
  138. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\" lci"):
  139. raise Exception("Request failed")
  140. check_nr_results(dev[0], ["00:11:22:33:44:55", "00:11:22:33:44:56"],
  141. lci=True)
  142. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\" civic"):
  143. raise Exception("Request failed")
  144. check_nr_results(dev[0], ["00:11:22:33:44:55", "00:11:22:33:44:56"],
  145. civic=True)
  146. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\" lci civic"):
  147. raise Exception("Request failed")
  148. check_nr_results(dev[0], ["00:11:22:33:44:55", "00:11:22:33:44:56"],
  149. lci=True, civic=True)
  150. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test4\""):
  151. raise Exception("Request failed")
  152. check_nr_results(dev[0], ["00:11:22:33:44:56"])
  153. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test4\" lci"):
  154. raise Exception("Request failed")
  155. check_nr_results(dev[0], ["00:11:22:33:44:56"], lci=True)
  156. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test4\" civic"):
  157. raise Exception("Request failed")
  158. check_nr_results(dev[0], ["00:11:22:33:44:56"], civic=True)
  159. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test4\" lci civic"):
  160. raise Exception("Request failed")
  161. check_nr_results(dev[0], ["00:11:22:33:44:56"], lci=True, civic=True)
  162. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test5\""):
  163. raise Exception("Request failed")
  164. check_nr_results(dev[0], ["dd:11:22:33:44:55"])
  165. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test5\" lci"):
  166. raise Exception("Request failed")
  167. check_nr_results(dev[0], ["dd:11:22:33:44:55"], lci=True)
  168. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test5\" civic"):
  169. raise Exception("Request failed")
  170. check_nr_results(dev[0], ["dd:11:22:33:44:55"])
  171. if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test5\" lci civic"):
  172. raise Exception("Request failed")
  173. check_nr_results(dev[0], ["dd:11:22:33:44:55"], lci=True)
  174. def test_rrm_lci_req(dev, apdev):
  175. """hostapd lci request"""
  176. rrm = int(dev[0].get_driver_status_field("capa.rrm_flags"), 16)
  177. if rrm & 0x5 != 0x5 and rrm & 0x10 != 0x10:
  178. raise HwsimSkip("Required RRM capabilities are not supported")
  179. params = { "ssid": "rrm", "rrm_neighbor_report": "1" }
  180. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  181. # station not specified
  182. if "FAIL" not in hapd.request("REQ_LCI "):
  183. raise Exception("REQ_LCI with no station succeeded unexpectedly")
  184. # station that is not connected specified
  185. if "FAIL" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
  186. raise Exception("REQ_LCI succeeded unexpectedly (station not connected)")
  187. dev[0].request("SET LCI ")
  188. dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
  189. # station connected without LCI
  190. if "FAIL" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
  191. raise Exception("REQ_LCI succeeded unexpectedly (station without lci)")
  192. dev[0].request("DISCONNECT")
  193. dev[0].wait_disconnected(timeout=2)
  194. dev[0].request("SET LCI " + lci)
  195. dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
  196. # station connected with LCI
  197. if "OK" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
  198. raise Exception("REQ_LCI failed unexpectedly")
  199. def test_rrm_ftm_range_req(dev, apdev):
  200. """hostapd FTM range request command"""
  201. rrm = int(dev[0].get_driver_status_field("capa.rrm_flags"), 16)
  202. if rrm & 0x5 != 0x5 and rrm & 0x10 != 0x10:
  203. raise HwsimSkip("Required RRM capabilities are not supported")
  204. params = { "ssid": "rrm", "rrm_neighbor_report": "1" }
  205. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  206. # station not specified
  207. if "FAIL" not in hapd.request("REQ_RANGE "):
  208. raise Exception("REQ_RANGE with no station succeeded unexpectedly")
  209. # station that is not connected specified
  210. if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr()):
  211. raise Exception("REQ_RANGE succeeded unexpectedly (station not connected)")
  212. # No responders specified
  213. if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 10"):
  214. raise Exception("REQ_RANGE succeeded unexpectedly (no responder)")
  215. # Bad responder address
  216. if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 10 00:11:22:33:44:"):
  217. raise Exception("REQ_RANGE succeeded unexpectedly (bad responder address)")
  218. # Bad responder address
  219. if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 10 00:11:22:33:44:55 00:11:22:33:44"):
  220. raise Exception("REQ_RANGE succeeded unexpectedly (bad responder address 2)")
  221. # Bad min_ap value
  222. if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 20 10 00:11:22:33:44:55"):
  223. raise Exception("REQ_RANGE succeeded unexpectedly (invalid min_ap value)")
  224. # Bad rand value
  225. if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 300 00:11:22:33:44:55"):
  226. raise Exception("REQ_RANGE succeeded unexpectedly (invalid rand value)")
  227. dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
  228. # Responder not in database
  229. # Note: this check would pass since the station does not support FTM range
  230. # request and not because the responder is not in the database.
  231. if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 10 00:11:22:33:44:55"):
  232. raise Exception("REQ_RANGE succeeded unexpectedly (responder not in database)")