tests: Mark 525 tests as remote compatible
[mech_eap.git] / tests / hwsim / test_mbo.py
1 # MBO tests
2 # Copyright (c) 2016, Intel Deutschland GmbH
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 from remotehost import remote_compatible
8 import logging
9 logger = logging.getLogger()
10
11 import hostapd
12 import os
13 import time
14
15 from tshark import run_tshark
16
17 def test_mbo_assoc_disallow(dev, apdev, params):
18     hapd1 = hostapd.add_ap(apdev[0], { "ssid": "MBO", "mbo": "1" })
19     hapd2 = hostapd.add_ap(apdev[1], { "ssid": "MBO", "mbo": "1" })
20
21     logger.debug("Set mbo_assoc_disallow with invalid value")
22     if "FAIL" not in hapd1.request("SET mbo_assoc_disallow 2"):
23         raise Exception("Set mbo_assoc_disallow for AP1 succeeded unexpectedly with value 2")
24
25     logger.debug("Disallow associations to AP1 and allow association to AP2")
26     if "OK" not in hapd1.request("SET mbo_assoc_disallow 1"):
27         raise Exception("Failed to set mbo_assoc_disallow for AP1")
28     if "OK" not in hapd2.request("SET mbo_assoc_disallow 0"):
29         raise Exception("Failed to set mbo_assoc_disallow for AP2")
30
31     dev[0].connect("MBO", key_mgmt="NONE", scan_freq="2412")
32
33     out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
34                      "wlan.fc.type == 0 && wlan.fc.type_subtype == 0x00",
35                      wait=False)
36     if "Destination address: " + hapd1.own_addr() in out:
37         raise Exception("Association request sent to disallowed AP")
38
39     timestamp = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
40                            "wlan.fc.type_subtype == 0x00",
41                            display=['frame.time'], wait=False)
42
43     logger.debug("Allow associations to AP1 and disallow assications to AP2")
44     if "OK" not in hapd1.request("SET mbo_assoc_disallow 0"):
45         raise Exception("Failed to set mbo_assoc_disallow for AP1")
46     if "OK" not in hapd2.request("SET mbo_assoc_disallow 1"):
47         raise Exception("Failed to set mbo_assoc_disallow for AP2")
48
49     dev[0].request("DISCONNECT")
50     dev[0].wait_disconnected()
51
52     # Force new scan, so the assoc_disallowed indication is updated */
53     dev[0].request("FLUSH")
54
55     dev[0].connect("MBO", key_mgmt="NONE", scan_freq="2412")
56
57     filter = 'wlan.fc.type == 0 && wlan.fc.type_subtype == 0x00 && frame.time > "' + timestamp.rstrip() + '"'
58     out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
59                      filter, wait=False)
60     if "Destination address: " + hapd2.own_addr() in out:
61         raise Exception("Association request sent to disallowed AP 2")
62
63 @remote_compatible
64 def test_mbo_cell_capa_update(dev, apdev):
65     """MBO cellular data capability update"""
66     ssid = "test-wnm-mbo"
67     params = { 'ssid': ssid, 'mbo': '1' }
68     hapd = hostapd.add_ap(apdev[0], params)
69     bssid = apdev[0]['bssid']
70     if "OK" not in dev[0].request("SET mbo_cell_capa 1"):
71         raise Exception("Failed to set STA as cellular data capable")
72
73     dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412")
74
75     addr = dev[0].own_addr()
76     sta = hapd.get_sta(addr)
77     if 'mbo_cell_capa' not in sta or sta['mbo_cell_capa'] != '1':
78         raise Exception("mbo_cell_capa missing after association")
79
80     if "OK" not in dev[0].request("SET mbo_cell_capa 3"):
81         raise Exception("Failed to set STA as cellular data not-capable")
82
83     time.sleep(0.2)
84     sta = hapd.get_sta(addr)
85     if 'mbo_cell_capa' not in sta:
86         raise Exception("mbo_cell_capa missing after update")
87     if sta['mbo_cell_capa'] != '3':
88         raise Exception("mbo_cell_capa not updated properly")
89
90 @remote_compatible
91 def test_mbo_cell_capa_update_pmf(dev, apdev):
92     """MBO cellular data capability update with PMF required"""
93     ssid = "test-wnm-mbo"
94     passphrase = "12345678"
95     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
96     params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
97     params["ieee80211w"] = "2";
98     params['mbo'] = '1'
99     hapd = hostapd.add_ap(apdev[0], params)
100     bssid = apdev[0]['bssid']
101     if "OK" not in dev[0].request("SET mbo_cell_capa 1"):
102         raise Exception("Failed to set STA as cellular data capable")
103
104     dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK-SHA256",
105                    proto="WPA2", ieee80211w="2", scan_freq="2412")
106
107     addr = dev[0].own_addr()
108     sta = hapd.get_sta(addr)
109     if 'mbo_cell_capa' not in sta or sta['mbo_cell_capa'] != '1':
110         raise Exception("mbo_cell_capa missing after association")
111
112     if "OK" not in dev[0].request("SET mbo_cell_capa 3"):
113         raise Exception("Failed to set STA as cellular data not-capable")
114
115     time.sleep(0.2)
116     sta = hapd.get_sta(addr)
117     if 'mbo_cell_capa' not in sta:
118         raise Exception("mbo_cell_capa missing after update")
119     if sta['mbo_cell_capa'] != '3':
120         raise Exception("mbo_cell_capa not updated properly")
121
122 @remote_compatible
123 def test_mbo_non_pref_chan(dev, apdev):
124     """MBO non-preferred channel list"""
125     ssid = "test-wnm-mbo"
126     params = { 'ssid': ssid, 'mbo': '1' }
127     hapd = hostapd.add_ap(apdev[0], params)
128     bssid = apdev[0]['bssid']
129     if "OK" not in dev[0].request("SET non_pref_chan 81:7:200:3"):
130         raise Exception("Failed to set non-preferred channel list")
131     if "OK" not in dev[0].request("SET non_pref_chan 81:7:200:1:123 81:9:100:2"):
132         raise Exception("Failed to set non-preferred channel list")
133
134     dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412")
135
136     addr = dev[0].own_addr()
137     sta = hapd.get_sta(addr)
138     logger.debug("STA: " + str(sta))
139     if 'non_pref_chan[0]' not in sta:
140         raise Exception("Missing non_pref_chan[0] value (assoc)")
141     if sta['non_pref_chan[0]'] != '81:200:1:123:7':
142         raise Exception("Unexpected non_pref_chan[0] value (assoc)")
143     if 'non_pref_chan[1]' not in sta:
144         raise Exception("Missing non_pref_chan[1] value (assoc)")
145     if sta['non_pref_chan[1]'] != '81:100:2:0:9':
146         raise Exception("Unexpected non_pref_chan[1] value (assoc)")
147     if 'non_pref_chan[2]' in sta:
148         raise Exception("Unexpected non_pref_chan[2] value (assoc)")
149
150     if "OK" not in dev[0].request("SET non_pref_chan 81:9:100:2"):
151         raise Exception("Failed to update non-preferred channel list")
152     time.sleep(0.1)
153     sta = hapd.get_sta(addr)
154     logger.debug("STA: " + str(sta))
155     if 'non_pref_chan[0]' not in sta:
156         raise Exception("Missing non_pref_chan[0] value (update 1)")
157     if sta['non_pref_chan[0]'] != '81:100:2:0:9':
158         raise Exception("Unexpected non_pref_chan[0] value (update 1)")
159     if 'non_pref_chan[1]' in sta:
160         raise Exception("Unexpected non_pref_chan[2] value (update 1)")
161
162     if "OK" not in dev[0].request("SET non_pref_chan 81:9:100:2 81:10:100:2 81:8:100:2 81:7:100:1:123 81:5:100:1:124"):
163         raise Exception("Failed to update non-preferred channel list")
164     time.sleep(0.1)
165     sta = hapd.get_sta(addr)
166     logger.debug("STA: " + str(sta))
167     if 'non_pref_chan[0]' not in sta:
168         raise Exception("Missing non_pref_chan[0] value (update 2)")
169     if sta['non_pref_chan[0]'] != '81:100:1:123:7':
170         raise Exception("Unexpected non_pref_chan[0] value (update 2)")
171     if 'non_pref_chan[1]' not in sta:
172         raise Exception("Missing non_pref_chan[1] value (update 2)")
173     if sta['non_pref_chan[1]'] != '81:100:1:124:5':
174         raise Exception("Unexpected non_pref_chan[1] value (update 2)")
175     if 'non_pref_chan[2]' not in sta:
176         raise Exception("Missing non_pref_chan[2] value (update 2)")
177     if sta['non_pref_chan[2]'] != '81:100:2:0:9,10,8':
178         raise Exception("Unexpected non_pref_chan[2] value (update 2)")
179     if 'non_pref_chan[3]' in sta:
180         raise Exception("Unexpected non_pref_chan[3] value (update 2)")
181
182     if "OK" not in dev[0].request("SET non_pref_chan 81:5:90:2 82:14:91:2"):
183         raise Exception("Failed to update non-preferred channel list")
184     time.sleep(0.1)
185     sta = hapd.get_sta(addr)
186     logger.debug("STA: " + str(sta))
187     if 'non_pref_chan[0]' not in sta:
188         raise Exception("Missing non_pref_chan[0] value (update 3)")
189     if sta['non_pref_chan[0]'] != '81:90:2:0:5':
190         raise Exception("Unexpected non_pref_chan[0] value (update 3)")
191     if 'non_pref_chan[1]' not in sta:
192         raise Exception("Missing non_pref_chan[1] value (update 3)")
193     if sta['non_pref_chan[1]'] != '82:91:2:0:14':
194         raise Exception("Unexpected non_pref_chan[1] value (update 3)")
195     if 'non_pref_chan[2]' in sta:
196         raise Exception("Unexpected non_pref_chan[2] value (update 3)")
197
198     if "OK" not in dev[0].request("SET non_pref_chan "):
199         raise Exception("Failed to update non-preferred channel list")
200     time.sleep(0.1)
201     sta = hapd.get_sta(addr)
202     logger.debug("STA: " + str(sta))
203     if 'non_pref_chan[0]' in sta:
204         raise Exception("Unexpected non_pref_chan[0] value (update 4)")
205
206 @remote_compatible
207 def test_mbo_sta_supp_op_classes(dev, apdev):
208     """MBO STA supported operating classes"""
209     ssid = "test-wnm-mbo"
210     params = { 'ssid': ssid, 'mbo': '1' }
211     hapd = hostapd.add_ap(apdev[0], params)
212
213     dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412")
214
215     addr = dev[0].own_addr()
216     sta = hapd.get_sta(addr)
217     logger.debug("STA: " + str(sta))
218     if 'supp_op_classes' not in sta:
219         raise Exception("No supp_op_classes")
220     supp = bytearray(sta['supp_op_classes'].decode("hex"))
221     if supp[0] != 81:
222         raise Exception("Unexpected current operating class %d" % supp[0])
223     if 115 not in supp:
224         raise Exception("Operating class 115 missing")