tests: Fix ap_track_taxonomy to clear country code setting
[mech_eap.git] / tests / hwsim / test_ap_track.py
1 # Test cases for hostapd tracking unconnected stations
2 # Copyright (c) 2015, 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
7 import logging
8 logger = logging.getLogger()
9 import subprocess
10 import time
11
12 import hostapd
13 from wpasupplicant import WpaSupplicant
14
15 def test_ap_track_sta(dev, apdev):
16     """Dualband AP tracking unconnected stations"""
17     try:
18         _test_ap_track_sta(dev, apdev)
19     finally:
20         subprocess.call(['iw', 'reg', 'set', '00'])
21
22 def _test_ap_track_sta(dev, apdev):
23     params = { "ssid": "track",
24                "country_code": "US",
25                "hw_mode": "g",
26                "channel": "6",
27                "track_sta_max_num": "2" }
28     hapd = hostapd.add_ap(apdev[0], params)
29     bssid = apdev[0]['bssid']
30
31     params = { "ssid": "track",
32                "country_code": "US",
33                "hw_mode": "a",
34                "channel": "40",
35                "track_sta_max_num": "100",
36                "track_sta_max_age": "1" }
37     hapd2 = hostapd.add_ap(apdev[1], params)
38     bssid2 = apdev[1]['bssid']
39
40     for i in range(2):
41         dev[0].scan_for_bss(bssid, freq=2437, force_scan=True)
42         dev[0].scan_for_bss(bssid2, freq=5200, force_scan=True)
43         dev[1].scan_for_bss(bssid, freq=2437, force_scan=True)
44         dev[2].scan_for_bss(bssid2, freq=5200, force_scan=True)
45
46     addr0 = dev[0].own_addr()
47     addr1 = dev[1].own_addr()
48     addr2 = dev[2].own_addr()
49
50     track = hapd.request("TRACK_STA_LIST")
51     if addr0 not in track or addr1 not in track:
52         raise Exception("Station missing from 2.4 GHz tracking")
53     if addr2 in track:
54         raise Exception("Unexpected station included in 2.4 GHz tracking")
55     
56     track = hapd2.request("TRACK_STA_LIST")
57     if addr0 not in track or addr2 not in track:
58         raise Exception("Station missing from 5 GHz tracking")
59     if addr1 in track:
60         raise Exception("Unexpected station included in 5 GHz tracking")
61
62     # Test expiration
63     time.sleep(1.1)
64     track = hapd.request("TRACK_STA_LIST")
65     if addr0 not in track or addr1 not in track:
66         raise Exception("Station missing from 2.4 GHz tracking (expiration)")
67     track = hapd2.request("TRACK_STA_LIST")
68     if addr0 in track or addr2 in track:
69         raise Exception("Station not expired from 5 GHz tracking")
70
71     # Test maximum list length
72     dev[0].scan_for_bss(bssid, freq=2437, force_scan=True)
73     dev[1].scan_for_bss(bssid, freq=2437, force_scan=True)
74     dev[2].scan_for_bss(bssid, freq=2437, force_scan=True)
75     track = hapd.request("TRACK_STA_LIST")
76     if len(track.splitlines()) != 2:
77         raise Exception("Unexpected number of entries: %d" % len(track.splitlines()))
78     if addr1 not in track or addr2 not in track:
79         raise Exception("Station missing from 2.4 GHz tracking (max limit)")
80
81 def test_ap_track_sta_no_probe_resp(dev, apdev):
82     """Dualband AP not replying to probes from dualband STA on 2.4 GHz"""
83     try:
84         _test_ap_track_sta_no_probe_resp(dev, apdev)
85     finally:
86         subprocess.call(['iw', 'reg', 'set', '00'])
87
88 def _test_ap_track_sta_no_probe_resp(dev, apdev):
89     dev[0].flush_scan_cache()
90
91     params = { "ssid": "track",
92                "country_code": "US",
93                "hw_mode": "g",
94                "channel": "6",
95                "beacon_int": "10000",
96                "no_probe_resp_if_seen_on": apdev[1]['ifname'] }
97     hapd = hostapd.add_ap(apdev[0], params)
98     bssid = apdev[0]['bssid']
99
100     params = { "ssid": "track",
101                "country_code": "US",
102                "hw_mode": "a",
103                "channel": "40",
104                "track_sta_max_num": "100" }
105     hapd2 = hostapd.add_ap(apdev[1], params)
106     bssid2 = apdev[1]['bssid']
107
108     dev[0].scan_for_bss(bssid2, freq=5200, force_scan=True)
109     dev[1].scan_for_bss(bssid, freq=2437, force_scan=True)
110     dev[0].scan(freq=2437, type="ONLY")
111     dev[0].scan(freq=2437, type="ONLY")
112
113     if dev[0].get_bss(bssid):
114         raise Exception("2.4 GHz AP found unexpectedly")
115
116 def test_ap_track_sta_no_auth(dev, apdev):
117     """Dualband AP rejecting authentication from dualband STA on 2.4 GHz"""
118     try:
119         _test_ap_track_sta_no_auth(dev, apdev)
120     finally:
121         subprocess.call(['iw', 'reg', 'set', '00'])
122
123 def _test_ap_track_sta_no_auth(dev, apdev):
124     params = { "ssid": "track",
125                "country_code": "US",
126                "hw_mode": "g",
127                "channel": "6",
128                "track_sta_max_num": "100",
129                "no_auth_if_seen_on": apdev[1]['ifname'] }
130     hapd = hostapd.add_ap(apdev[0], params)
131     bssid = apdev[0]['bssid']
132
133     params = { "ssid": "track",
134                "country_code": "US",
135                "hw_mode": "a",
136                "channel": "40",
137                "track_sta_max_num": "100" }
138     hapd2 = hostapd.add_ap(apdev[1], params)
139     bssid2 = apdev[1]['bssid']
140
141     dev[0].scan_for_bss(bssid, freq=2437, force_scan=True)
142     dev[0].scan_for_bss(bssid2, freq=5200, force_scan=True)
143     dev[1].scan_for_bss(bssid, freq=2437, force_scan=True)
144
145     dev[1].connect("track", key_mgmt="NONE", scan_freq="2437")
146
147     dev[0].connect("track", key_mgmt="NONE", scan_freq="2437",
148                    freq_list="2437", wait_connect=False)
149     dev[1].request("DISCONNECT")
150     ev = dev[0].wait_event([ "CTRL-EVENT-CONNECTED",
151                              "CTRL-EVENT-AUTH-REJECT" ], timeout=10)
152     if ev is None:
153         raise Exception("Unknown connection result")
154     if "CTRL-EVENT-CONNECTED" in ev:
155         raise Exception("Unexpected connection")
156     if "status_code=82" not in ev:
157         raise Exception("Unexpected rejection reason: " + ev)
158     if "ie=34" not in ev:
159         raise Exception("No Neighbor Report element: " + ev)
160     dev[0].request("DISCONNECT")
161
162 def test_ap_track_sta_no_auth_passive(dev, apdev):
163     """AP rejecting authentication from dualband STA on 2.4 GHz (passive)"""
164     try:
165         _test_ap_track_sta_no_auth_passive(dev, apdev)
166     finally:
167         subprocess.call(['iw', 'reg', 'set', '00'])
168
169 def _test_ap_track_sta_no_auth_passive(dev, apdev):
170     dev[0].flush_scan_cache()
171
172     params = { "ssid": "track",
173                "country_code": "US",
174                "hw_mode": "g",
175                "channel": "6",
176                "no_auth_if_seen_on": apdev[1]['ifname'] }
177     hapd = hostapd.add_ap(apdev[0], params)
178     bssid = apdev[0]['bssid']
179
180     params = { "ssid": "track",
181                "country_code": "US",
182                "hw_mode": "a",
183                "channel": "40",
184                "interworking": "1",
185                "venue_name": "eng:Venue",
186                "track_sta_max_num": "100" }
187     hapd2 = hostapd.add_ap(apdev[1], params)
188     bssid2 = apdev[1]['bssid']
189
190     dev[0].scan_for_bss(bssid, freq=2437, force_scan=True)
191     for i in range(10):
192         dev[0].request("SCAN freq=5200 passive=1")
193         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=5)
194         if ev is None:
195             raise Exception("Scan did not complete")
196         if dev[0].get_bss(bssid2):
197             break
198         if i == 9:
199             raise Exception("AP not found with passive scans")
200
201     if "OK" not in dev[0].request("ANQP_GET " + bssid2 + " 258"):
202         raise Exception("ANQP_GET command failed")
203     ev = dev[0].wait_event(["RX-ANQP"], timeout=1)
204     if ev is None or "Venue Name" not in ev:
205         raise Exception("Did not receive Venue Name")
206
207     dev[0].connect("track", key_mgmt="NONE", scan_freq="2437",
208                    freq_list="2437", wait_connect=False)
209     ev = dev[0].wait_event([ "CTRL-EVENT-CONNECTED",
210                              "CTRL-EVENT-AUTH-REJECT" ], timeout=10)
211     if ev is None:
212         raise Exception("Unknown connection result")
213     if "CTRL-EVENT-CONNECTED" in ev:
214         raise Exception("Unexpected connection")
215     if "status_code=82" not in ev:
216         raise Exception("Unexpected rejection reason: " + ev)
217     dev[0].request("DISCONNECT")
218
219 def test_ap_track_sta_force_5ghz(dev, apdev):
220     """Dualband AP forcing dualband STA to connect on 5 GHz"""
221     try:
222         _test_ap_track_sta_force_5ghz(dev, apdev)
223     finally:
224         subprocess.call(['iw', 'reg', 'set', '00'])
225
226 def _test_ap_track_sta_force_5ghz(dev, apdev):
227     params = { "ssid": "track",
228                "country_code": "US",
229                "hw_mode": "g",
230                "channel": "6",
231                "no_probe_resp_if_seen_on": apdev[1]['ifname'],
232                "no_auth_if_seen_on": apdev[1]['ifname'] }
233     hapd = hostapd.add_ap(apdev[0], params)
234     bssid = apdev[0]['bssid']
235
236     params = { "ssid": "track",
237                "country_code": "US",
238                "hw_mode": "a",
239                "channel": "40",
240                "track_sta_max_num": "100" }
241     hapd2 = hostapd.add_ap(apdev[1], params)
242     bssid2 = apdev[1]['bssid']
243
244     dev[0].scan_for_bss(bssid, freq=2437, force_scan=True)
245     dev[0].scan_for_bss(bssid2, freq=5200, force_scan=True)
246
247     dev[0].connect("track", key_mgmt="NONE", scan_freq="2437 5200")
248     freq = dev[0].get_status_field('freq')
249     if freq != '5200':
250         raise Exception("Unexpected operating channel")
251     dev[0].request("DISCONNECT")
252
253 def test_ap_track_sta_force_2ghz(dev, apdev):
254     """Dualband AP forcing dualband STA to connect on 2.4 GHz"""
255     try:
256         _test_ap_track_sta_force_2ghz(dev, apdev)
257     finally:
258         subprocess.call(['iw', 'reg', 'set', '00'])
259
260 def _test_ap_track_sta_force_2ghz(dev, apdev):
261     params = { "ssid": "track",
262                "country_code": "US",
263                "hw_mode": "g",
264                "channel": "6",
265                "track_sta_max_num": "100" }
266     hapd = hostapd.add_ap(apdev[0], params)
267     bssid = apdev[0]['bssid']
268
269     params = { "ssid": "track",
270                "country_code": "US",
271                "hw_mode": "a",
272                "channel": "40",
273                "no_probe_resp_if_seen_on": apdev[0]['ifname'],
274                "no_auth_if_seen_on": apdev[0]['ifname'] }
275     hapd2 = hostapd.add_ap(apdev[1], params)
276     bssid2 = apdev[1]['bssid']
277
278     dev[0].scan_for_bss(bssid2, freq=5200, force_scan=True)
279     dev[0].scan_for_bss(bssid, freq=2437, force_scan=True)
280
281     dev[0].connect("track", key_mgmt="NONE", scan_freq="2437 5200")
282     freq = dev[0].get_status_field('freq')
283     if freq != '2437':
284         raise Exception("Unexpected operating channel")
285     dev[0].request("DISCONNECT")
286
287 def test_ap_track_taxonomy(dev, apdev):
288     """AP tracking STA taxonomy"""
289     try:
290         _test_ap_track_taxonomy(dev, apdev)
291     finally:
292         dev[1].request("SET p2p_disabled 0")
293         subprocess.call(['iw', 'reg', 'set', '00'])
294         dev[0].flush_scan_cache()
295         dev[1].flush_scan_cache()
296         dev[2].flush_scan_cache()
297
298 def _test_ap_track_taxonomy(dev, apdev):
299     params = { "ssid": "track",
300                "country_code": "US",
301                "hw_mode": "g",
302                "channel": "6",
303                "track_sta_max_num": "2" }
304     hapd = hostapd.add_ap(apdev[0], params)
305     bssid = apdev[0]['bssid']
306
307     dev[0].scan_for_bss(bssid, freq=2437, force_scan=True)
308     addr0 = dev[0].own_addr()
309     dev[0].connect("track", key_mgmt="NONE", scan_freq="2437")
310
311     dev[1].request("SET p2p_disabled 1")
312     dev[1].scan_for_bss(bssid, freq=2437, force_scan=True)
313     addr1 = dev[1].own_addr()
314     dev[1].connect("track", key_mgmt="NONE", scan_freq="2437")
315
316     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
317     wpas.interface_add("wlan5")
318     wpas.request("SET model_name track test")
319     wpas.scan_for_bss(bssid, freq=2437, force_scan=True)
320     addr = wpas.own_addr()
321     wpas.connect("track", key_mgmt="NONE", scan_freq="2437")
322
323     if "FAIL" not in hapd.request("SIGNATURE abc"):
324         raise Exception("SIGNATURE failure not reported (1)")
325     if "FAIL" not in hapd.request("SIGNATURE 22:33:44:55:66:77"):
326         raise Exception("SIGNATURE failure not reported (2)")
327
328     res = hapd.request("SIGNATURE " + addr0)
329     logger.info("sta0: " + res)
330     if not res.startswith("wifi4|probe:"):
331         raise Exception("Unexpected SIGNATURE prefix")
332     if "|assoc:" not in res:
333         raise Exception("Missing assoc info in SIGNATURE")
334     if "wps:track_test" in res:
335         raise Exception("Unexpected WPS model name")
336
337     res = hapd.request("SIGNATURE " + addr1)
338     logger.info("sta1: " + res)
339     if not res.startswith("wifi4|probe:"):
340         raise Exception("Unexpected SIGNATURE prefix")
341     if "|assoc:" not in res:
342         raise Exception("Missing assoc info in SIGNATURE")
343     if "wps:" in res:
344         raise Exception("Unexpected WPS info");
345     if ",221(0050f2,4)," in res:
346         raise Exception("Unexpected WPS IE info");
347     if ",221(506f9a,9)," in res:
348         raise Exception("Unexpected P2P IE info");
349
350     res = hapd.request("SIGNATURE " + addr)
351     logger.info("sta: " + res)
352     if not res.startswith("wifi4|probe:"):
353         raise Exception("Unexpected SIGNATURE prefix")
354     if "|assoc:" not in res:
355         raise Exception("Missing assoc info in SIGNATURE")
356     if "wps:track_test" not in res:
357         raise Exception("Missing WPS model name")
358     if ",221(0050f2,4)," not in res:
359         raise Exception("Missing WPS IE info");
360     if ",221(506f9a,9)," not in res:
361         raise Exception("Missing P2P IE info");
362
363     addr2 = dev[2].own_addr()
364     res = hapd.request("SIGNATURE " + addr2)
365     if "FAIL" not in res:
366         raise Exception("Unexpected SIGNATURE success for sta2 (1)")
367
368     for i in range(10):
369         dev[2].request("SCAN freq=2437 passive=1")
370         ev = dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
371         if ev is None:
372             raise Exception("Scan did not complete")
373         if dev[2].get_bss(bssid):
374             break
375
376     res = hapd.request("SIGNATURE " + addr2)
377     if "FAIL" not in res:
378         raise Exception("Unexpected SIGNATURE success for sta2 (2)")
379
380     dev[2].connect("track", key_mgmt="NONE", scan_freq="2437")
381
382     res = hapd.request("SIGNATURE " + addr2)
383     if "FAIL" not in res and len(res) > 0:
384         raise Exception("Unexpected SIGNATURE success for sta2 (3)")
385
386     dev[2].scan_for_bss(bssid, freq=2437, force_scan=True)
387
388     res = hapd.request("SIGNATURE " + addr2)
389     logger.info("sta2: " + res)
390     if not res.startswith("wifi4|probe:"):
391         raise Exception("Unexpected SIGNATURE prefix")
392     if "|assoc:" not in res:
393         raise Exception("Missing assoc info in SIGNATURE")