test_scan.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. # Scanning tests
  2. # Copyright (c) 2013, 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 subprocess
  10. import hostapd
  11. def check_scan(dev, params, other_started=False):
  12. if not other_started:
  13. dev.dump_monitor()
  14. id = dev.request("SCAN " + params)
  15. if "FAIL" in id:
  16. raise Exception("Failed to start scan")
  17. id = int(id)
  18. if other_started:
  19. ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"])
  20. if ev is None:
  21. raise Exception("Other scan did not start")
  22. if "id=" + str(id) in ev:
  23. raise Exception("Own scan id unexpectedly included in start event")
  24. ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"])
  25. if ev is None:
  26. raise Exception("Other scan did not complete")
  27. if "id=" + str(id) in ev:
  28. raise Exception("Own scan id unexpectedly included in completed event")
  29. ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"])
  30. if ev is None:
  31. raise Exception("Scan did not start")
  32. if "id=" + str(id) not in ev:
  33. raise Exception("Scan id not included in start event")
  34. ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"])
  35. if ev is None:
  36. raise Exception("Scan did not complete")
  37. if "id=" + str(id) not in ev:
  38. raise Exception("Scan id not included in completed event")
  39. def test_scan(dev, apdev):
  40. """Control interface behavior on scan parameters"""
  41. hostapd.add_ap(apdev[0]['ifname'], { "ssid": "test-scan" })
  42. bssid = apdev[0]['bssid']
  43. logger.info("Full scan")
  44. check_scan(dev[0], "use_id=1")
  45. logger.info("Limited channel scan")
  46. check_scan(dev[0], "freq=2412-2462,5180 use_id=1")
  47. if int(dev[0].get_bss(bssid)['age']) > 1:
  48. raise Exception("Unexpectedly old BSS entry")
  49. # wait long enough to allow next scans to be verified not to find the AP
  50. time.sleep(2)
  51. logger.info("Passive single-channel scan")
  52. check_scan(dev[0], "freq=2457 passive=1 use_id=1")
  53. logger.info("Active single-channel scan")
  54. check_scan(dev[0], "freq=2452 passive=0 use_id=1")
  55. if int(dev[0].get_bss(bssid)['age']) < 2:
  56. raise Exception("Unexpectedly updated BSS entry")
  57. logger.info("Active single-channel scan on AP's operating channel")
  58. check_scan(dev[0], "freq=2412 passive=0 use_id=1")
  59. if int(dev[0].get_bss(bssid)['age']) > 1:
  60. raise Exception("Unexpectedly old BSS entry")
  61. def test_scan_only(dev, apdev):
  62. """Control interface behavior on scan parameters with type=only"""
  63. hostapd.add_ap(apdev[0]['ifname'], { "ssid": "test-scan" })
  64. bssid = apdev[0]['bssid']
  65. logger.info("Full scan")
  66. check_scan(dev[0], "type=only use_id=1")
  67. logger.info("Limited channel scan")
  68. check_scan(dev[0], "type=only freq=2412-2462,5180 use_id=1")
  69. if int(dev[0].get_bss(bssid)['age']) > 1:
  70. raise Exception("Unexpectedly old BSS entry")
  71. # wait long enough to allow next scans to be verified not to find the AP
  72. time.sleep(2)
  73. logger.info("Passive single-channel scan")
  74. check_scan(dev[0], "type=only freq=2457 passive=1 use_id=1")
  75. logger.info("Active single-channel scan")
  76. check_scan(dev[0], "type=only freq=2452 passive=0 use_id=1")
  77. if int(dev[0].get_bss(bssid)['age']) < 2:
  78. raise Exception("Unexpectedly updated BSS entry")
  79. logger.info("Active single-channel scan on AP's operating channel")
  80. check_scan(dev[0], "type=only freq=2412 passive=0 use_id=1")
  81. if int(dev[0].get_bss(bssid)['age']) > 1:
  82. raise Exception("Unexpectedly old BSS entry")
  83. def test_scan_external_trigger(dev, apdev):
  84. """Avoid operations during externally triggered scan"""
  85. hostapd.add_ap(apdev[0]['ifname'], { "ssid": "test-scan" })
  86. bssid = apdev[0]['bssid']
  87. subprocess.call(['sudo', 'iw', dev[0].ifname, 'scan', 'trigger'])
  88. check_scan(dev[0], "use_id=1", other_started=True)
  89. def test_scan_bss_expiration_count(dev, apdev):
  90. """BSS entry expiration based on scan results without match"""
  91. if "FAIL" not in dev[0].request("BSS_EXPIRE_COUNT 0"):
  92. raise Exception("Invalid BSS_EXPIRE_COUNT accepted")
  93. if "OK" not in dev[0].request("BSS_EXPIRE_COUNT 2"):
  94. raise Exception("BSS_EXPIRE_COUNT failed")
  95. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "test-scan" })
  96. bssid = apdev[0]['bssid']
  97. dev[0].scan(freq="2412", only_new=True)
  98. if bssid not in dev[0].request("SCAN_RESULTS"):
  99. raise Exception("BSS not found in initial scan")
  100. hapd.request("DISABLE")
  101. dev[0].scan(freq="2412", only_new=True)
  102. if bssid not in dev[0].request("SCAN_RESULTS"):
  103. raise Exception("BSS not found in first scan without match")
  104. dev[0].scan(freq="2412", only_new=True)
  105. if bssid in dev[0].request("SCAN_RESULTS"):
  106. raise Exception("BSS found after two scans without match")
  107. def test_scan_bss_expiration_age(dev, apdev):
  108. """BSS entry expiration based on age"""
  109. try:
  110. if "FAIL" not in dev[0].request("BSS_EXPIRE_AGE COUNT 9"):
  111. raise Exception("Invalid BSS_EXPIRE_AGE accepted")
  112. if "OK" not in dev[0].request("BSS_EXPIRE_AGE 10"):
  113. raise Exception("BSS_EXPIRE_AGE failed")
  114. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "test-scan" })
  115. bssid = apdev[0]['bssid']
  116. dev[0].scan(freq="2412")
  117. if bssid not in dev[0].request("SCAN_RESULTS"):
  118. raise Exception("BSS not found in initial scan")
  119. hapd.request("DISABLE")
  120. logger.info("Waiting for BSS entry to expire")
  121. time.sleep(7)
  122. if bssid not in dev[0].request("SCAN_RESULTS"):
  123. raise Exception("BSS expired too quickly")
  124. ev = dev[0].wait_event(["CTRL-EVENT-BSS-REMOVED"], timeout=15)
  125. if ev is None:
  126. raise Exception("BSS entry expiration timed out")
  127. if bssid in dev[0].request("SCAN_RESULTS"):
  128. raise Exception("BSS not removed after expiration time")
  129. finally:
  130. dev[0].request("BSS_EXPIRE_AGE 180")