4 # Copyright (c) 2013, Qualcomm Atheros, Inc.
6 # This software may be distributed under the terms of the BSD license.
7 # See README for more details.
12 logger = logging.getLogger()
18 params = hostapd.wpa2_params(ssid="test-gas")
19 params['wpa_key_mgmt'] = "WPA-EAP"
20 params['ieee80211w'] = "1"
21 params['ieee8021x'] = "1"
22 params['auth_server_addr'] = "127.0.0.1"
23 params['auth_server_port'] = "1812"
24 params['auth_server_shared_secret'] = "radius"
25 params['interworking'] = "1"
26 params['access_network_type'] = "14"
27 params['internet'] = "1"
31 params['venue_group'] = "7"
32 params['venue_type'] = "1"
33 params['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
34 params['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
36 params['domain_name'] = "example.com,another.example.com"
37 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
38 "0,another.example.com" ]
39 params['anqp_3gpp_cell_net'] = "244,91"
42 def get_gas_response(dev, bssid, info, allow_fetch_failure=False):
43 exp = r'<.>(GAS-RESPONSE-INFO) addr=([0-9a-f:]*) dialog_token=([0-9]*) status_code=([0-9]*) resp_len=([\-0-9]*)'
44 res = re.split(exp, info)
46 raise Exception("Could not parse GAS-RESPONSE-INFO")
48 raise Exception("Unexpected BSSID in response")
52 raise Exception("GAS query failed")
55 raise Exception("GAS query reported invalid response length")
56 if int(resp_len) > 2000:
57 raise Exception("Unexpected long GAS response")
59 resp = dev.request("GAS_RESPONSE_GET " + bssid + " " + token)
61 if allow_fetch_failure:
62 logger.debug("GAS response was not available anymore")
64 raise Exception("Could not fetch GAS response")
65 if len(resp) != int(resp_len) * 2:
66 raise Exception("Unexpected GAS response length")
67 logger.debug("GAS response: " + resp)
69 def test_gas_generic(dev, apdev):
70 """Generic GAS query"""
71 bssid = apdev[0]['bssid']
72 params = hs20_ap_params()
73 params['hessid'] = bssid
74 hostapd.add_ap(apdev[0]['ifname'], params)
77 req = dev[0].request("GAS_REQUEST " + bssid + " 00 000102000101")
79 raise Exception("GAS query request rejected")
80 ev = dev[0].wait_event(["GAS-RESPONSE-INFO"], timeout=10)
82 raise Exception("GAS query timed out")
83 get_gas_response(dev[0], bssid, ev)
85 def test_gas_concurrent_scan(dev, apdev):
86 """Generic GAS queries with concurrent scan operation"""
87 bssid = apdev[0]['bssid']
88 params = hs20_ap_params()
89 params['hessid'] = bssid
90 hostapd.add_ap(apdev[0]['ifname'], params)
94 logger.info("Request concurrent operations")
95 req = dev[0].request("GAS_REQUEST " + bssid + " 00 000102000101")
97 raise Exception("GAS query request rejected")
98 req = dev[0].request("GAS_REQUEST " + bssid + " 00 000102000801")
100 raise Exception("GAS query request rejected")
101 dev[0].request("SCAN")
102 req = dev[0].request("GAS_REQUEST " + bssid + " 00 000102000201")
104 raise Exception("GAS query request rejected")
105 req = dev[0].request("GAS_REQUEST " + bssid + " 00 000102000501")
107 raise Exception("GAS query request rejected")
110 for i in range(0, 5):
111 ev = dev[0].wait_event(["GAS-RESPONSE-INFO", "CTRL-EVENT-SCAN-RESULTS"],
114 raise Exception("Operation timed out")
115 if "GAS-RESPONSE-INFO" in ev:
116 responses = responses + 1
117 get_gas_response(dev[0], bssid, ev, allow_fetch_failure=True)
120 raise Exception("Unexpected number of GAS responses")
122 def test_gas_concurrent_connect(dev, apdev):
123 """Generic GAS queries with concurrent connection operation"""
124 bssid = apdev[0]['bssid']
125 params = hs20_ap_params()
126 params['hessid'] = bssid
127 hostapd.add_ap(apdev[0]['ifname'], params)
131 logger.debug("Start concurrent connect and GAS request")
132 dev[0].connect("test-gas", key_mgmt="WPA-EAP", eap="TTLS",
133 identity="DOMAIN\mschapv2 user", anonymous_identity="ttls",
134 password="password", phase2="auth=MSCHAPV2",
135 ca_cert="auth_serv/ca.pem", wait_connect=False)
136 req = dev[0].request("GAS_REQUEST " + bssid + " 00 000102000101")
138 raise Exception("GAS query request rejected")
140 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", "GAS-RESPONSE-INFO"],
143 raise Exception("Operation timed out")
144 if "CTRL-EVENT-CONNECTED" not in ev:
145 raise Exception("Unexpected operation order")
147 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", "GAS-RESPONSE-INFO"],
150 raise Exception("Operation timed out")
151 if "GAS-RESPONSE-INFO" not in ev:
152 raise Exception("Unexpected operation order")
153 get_gas_response(dev[0], bssid, ev)
155 dev[0].request("DISCONNECT")
156 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=5)
158 raise Exception("Disconnection timed out")
160 logger.debug("Wait six seconds for expiration of connect-without-scan")
163 logger.debug("Start concurrent GAS request and connect")
164 req = dev[0].request("GAS_REQUEST " + bssid + " 00 000102000101")
166 raise Exception("GAS query request rejected")
167 dev[0].request("RECONNECT")
169 ev = dev[0].wait_event(["GAS-RESPONSE-INFO"], timeout=10)
171 raise Exception("Operation timed out")
172 get_gas_response(dev[0], bssid, ev)
174 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=20)
176 raise Exception("No new scan results reported")
178 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=20)
180 raise Exception("Operation timed out")
181 if "CTRL-EVENT-CONNECTED" not in ev:
182 raise Exception("Unexpected operation order")
184 def test_gas_fragment(dev, apdev):
185 """GAS fragmentation"""
186 bssid = apdev[0]['bssid']
187 params = hs20_ap_params()
188 params['hessid'] = bssid
189 hostapd.add_ap(apdev[0]['ifname'], params)
190 hapd = hostapd.Hostapd(apdev[0]['ifname'])
191 hapd.set("gas_frag_limit", "50")
193 dev[0].scan(freq="2412")
194 dev[0].request("FETCH_ANQP")
195 for i in range(0, 6):
196 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
198 raise Exception("Operation timed out")
200 def test_gas_comeback_delay(dev, apdev):
201 """GAS fragmentation"""
202 bssid = apdev[0]['bssid']
203 params = hs20_ap_params()
204 params['hessid'] = bssid
205 hostapd.add_ap(apdev[0]['ifname'], params)
206 hapd = hostapd.Hostapd(apdev[0]['ifname'])
207 hapd.set("gas_comeback_delay", "500")
209 dev[0].scan(freq="2412")
210 dev[0].request("FETCH_ANQP")
211 for i in range(0, 6):
212 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
214 raise Exception("Operation timed out")
216 def expect_gas_result(dev, result):
217 ev = dev.wait_event(["GAS-QUERY-DONE"], timeout=10)
219 raise Exception("GAS query timed out")
220 if "result=" + result not in ev:
221 raise Exception("Unexpected GAS query result")
223 def test_gas_timeout(dev, apdev):
225 bssid = apdev[0]['bssid']
226 params = hs20_ap_params()
227 params['hessid'] = bssid
228 hostapd.add_ap(apdev[0]['ifname'], params)
229 hapd = hostapd.Hostapd(apdev[0]['ifname'])
231 dev[0].scan(freq="2412")
232 hapd.set("ext_mgmt_frame_handling", "1")
234 dev[0].request("ANQP_GET " + bssid + " 263")
235 ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=5)
237 raise Exception("GAS query start timed out")
239 ev = hapd.wait_event(["MGMT-RX"], timeout=5)
241 raise Exception("MGMT RX wait timed out")
243 expect_gas_result(dev[0], "TIMEOUT")
245 def test_gas_invalid_response_type(dev, apdev):
246 """GAS invalid response type"""
247 bssid = apdev[0]['bssid']
248 params = hs20_ap_params()
249 params['hessid'] = bssid
250 hostapd.add_ap(apdev[0]['ifname'], params)
251 hapd = hostapd.Hostapd(apdev[0]['ifname'])
253 dev[0].scan(freq="2412")
254 hapd.set("ext_mgmt_frame_handling", "1")
256 dev[0].request("ANQP_GET " + bssid + " 263")
257 ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=5)
259 raise Exception("GAS query start timed out")
261 query = hapd.mgmt_rx()
263 raise Exception("GAS query request not received")
265 resp['fc'] = query['fc']
266 resp['da'] = query['sa']
267 resp['sa'] = query['da']
268 resp['bssid'] = query['bssid']
269 # GAS Comeback Response instead of GAS Initial Response
270 resp['payload'] = binascii.unhexlify("040d" + binascii.hexlify(query['payload'][2]) + "0000000000" + "6c027f00" + "0000")
272 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
274 raise Exception("Missing TX status for GAS response")
276 raise Exception("GAS response not acknowledged")
278 # station drops the invalid frame, so this needs to result in GAS timeout
279 expect_gas_result(dev[0], "TIMEOUT")