xref: /freebsd/contrib/wpa/wpa_supplicant/notify.c (revision a90b9d0159070121c221b966469c3e36d912bf82)
1 /*
2  * wpa_supplicant - Event notifications
3  * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "common/wpa_ctrl.h"
13 #include "config.h"
14 #include "wpa_supplicant_i.h"
15 #include "wps_supplicant.h"
16 #include "binder/binder.h"
17 #include "dbus/dbus_common.h"
18 #include "dbus/dbus_new.h"
19 #include "rsn_supp/wpa.h"
20 #include "rsn_supp/pmksa_cache.h"
21 #include "fst/fst.h"
22 #include "crypto/tls.h"
23 #include "bss.h"
24 #include "driver_i.h"
25 #include "scan.h"
26 #include "p2p_supplicant.h"
27 #include "sme.h"
28 #include "notify.h"
29 
wpas_notify_supplicant_initialized(struct wpa_global * global)30 int wpas_notify_supplicant_initialized(struct wpa_global *global)
31 {
32 #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
33 	if (global->params.dbus_ctrl_interface) {
34 		global->dbus = wpas_dbus_init(global);
35 		if (global->dbus == NULL)
36 			return -1;
37 	}
38 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
39 
40 #ifdef CONFIG_BINDER
41 	global->binder = wpas_binder_init(global);
42 	if (!global->binder)
43 		return -1;
44 #endif /* CONFIG_BINDER */
45 
46 	return 0;
47 }
48 
49 
wpas_notify_supplicant_deinitialized(struct wpa_global * global)50 void wpas_notify_supplicant_deinitialized(struct wpa_global *global)
51 {
52 #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
53 	if (global->dbus)
54 		wpas_dbus_deinit(global->dbus);
55 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
56 
57 #ifdef CONFIG_BINDER
58 	if (global->binder)
59 		wpas_binder_deinit(global->binder);
60 #endif /* CONFIG_BINDER */
61 }
62 
63 
wpas_notify_iface_added(struct wpa_supplicant * wpa_s)64 int wpas_notify_iface_added(struct wpa_supplicant *wpa_s)
65 {
66 	if (wpa_s->p2p_mgmt)
67 		return 0;
68 
69 	if (wpas_dbus_register_interface(wpa_s))
70 		return -1;
71 
72 	return 0;
73 }
74 
75 
wpas_notify_iface_removed(struct wpa_supplicant * wpa_s)76 void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s)
77 {
78 	if (wpa_s->p2p_mgmt)
79 		return;
80 
81 	/* unregister interface in new DBus ctrl iface */
82 	wpas_dbus_unregister_interface(wpa_s);
83 }
84 
85 
wpas_notify_state_changed(struct wpa_supplicant * wpa_s,enum wpa_states new_state,enum wpa_states old_state)86 void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
87 			       enum wpa_states new_state,
88 			       enum wpa_states old_state)
89 {
90 	if (wpa_s->p2p_mgmt)
91 		return;
92 
93 	/* notify the new DBus API */
94 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATE);
95 
96 #ifdef CONFIG_FST
97 	if (wpa_s->fst && !is_zero_ether_addr(wpa_s->bssid)) {
98 		if (new_state == WPA_COMPLETED)
99 			fst_notify_peer_connected(wpa_s->fst, wpa_s->bssid);
100 		else if (old_state >= WPA_ASSOCIATED &&
101 			 new_state < WPA_ASSOCIATED)
102 			fst_notify_peer_disconnected(wpa_s->fst, wpa_s->bssid);
103 	}
104 #endif /* CONFIG_FST */
105 
106 	if (new_state == WPA_COMPLETED)
107 		wpas_p2p_notif_connected(wpa_s);
108 	else if (old_state >= WPA_ASSOCIATED && new_state < WPA_ASSOCIATED)
109 		wpas_p2p_notif_disconnected(wpa_s);
110 
111 	sme_state_changed(wpa_s);
112 
113 #ifdef ANDROID
114 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_STATE_CHANGE
115 		     "id=%d state=%d BSSID=" MACSTR " SSID=%s",
116 		     wpa_s->current_ssid ? wpa_s->current_ssid->id : -1,
117 		     new_state,
118 		     MAC2STR(wpa_s->bssid),
119 		     wpa_s->current_ssid && wpa_s->current_ssid->ssid ?
120 		     wpa_ssid_txt(wpa_s->current_ssid->ssid,
121 				  wpa_s->current_ssid->ssid_len) : "");
122 #endif /* ANDROID */
123 }
124 
125 
wpas_notify_disconnect_reason(struct wpa_supplicant * wpa_s)126 void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s)
127 {
128 	if (wpa_s->p2p_mgmt)
129 		return;
130 
131 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_DISCONNECT_REASON);
132 }
133 
134 
wpas_notify_auth_status_code(struct wpa_supplicant * wpa_s)135 void wpas_notify_auth_status_code(struct wpa_supplicant *wpa_s)
136 {
137 	if (wpa_s->p2p_mgmt)
138 		return;
139 
140 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_AUTH_STATUS_CODE);
141 }
142 
143 
wpas_notify_assoc_status_code(struct wpa_supplicant * wpa_s)144 void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s)
145 {
146 	if (wpa_s->p2p_mgmt)
147 		return;
148 
149 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ASSOC_STATUS_CODE);
150 }
151 
152 
wpas_notify_roam_time(struct wpa_supplicant * wpa_s)153 void wpas_notify_roam_time(struct wpa_supplicant *wpa_s)
154 {
155 	if (wpa_s->p2p_mgmt)
156 		return;
157 
158 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ROAM_TIME);
159 }
160 
161 
wpas_notify_roam_complete(struct wpa_supplicant * wpa_s)162 void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s)
163 {
164 	if (wpa_s->p2p_mgmt)
165 		return;
166 
167 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ROAM_COMPLETE);
168 }
169 
170 
wpas_notify_session_length(struct wpa_supplicant * wpa_s)171 void wpas_notify_session_length(struct wpa_supplicant *wpa_s)
172 {
173 	if (wpa_s->p2p_mgmt)
174 		return;
175 
176 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SESSION_LENGTH);
177 }
178 
179 
wpas_notify_bss_tm_status(struct wpa_supplicant * wpa_s)180 void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
181 {
182 	if (wpa_s->p2p_mgmt)
183 		return;
184 
185 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSS_TM_STATUS);
186 }
187 
188 
wpas_notify_network_changed(struct wpa_supplicant * wpa_s)189 void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)
190 {
191 	if (wpa_s->p2p_mgmt)
192 		return;
193 
194 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_NETWORK);
195 }
196 
197 
wpas_notify_ap_scan_changed(struct wpa_supplicant * wpa_s)198 void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s)
199 {
200 	if (wpa_s->p2p_mgmt)
201 		return;
202 
203 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_AP_SCAN);
204 }
205 
206 
wpas_notify_bssid_changed(struct wpa_supplicant * wpa_s)207 void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s)
208 {
209 	if (wpa_s->p2p_mgmt)
210 		return;
211 
212 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_BSS);
213 }
214 
215 
wpas_notify_mac_address_changed(struct wpa_supplicant * wpa_s)216 void wpas_notify_mac_address_changed(struct wpa_supplicant *wpa_s)
217 {
218 	if (wpa_s->p2p_mgmt)
219 		return;
220 
221 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_MAC_ADDRESS);
222 }
223 
224 
wpas_notify_auth_changed(struct wpa_supplicant * wpa_s)225 void wpas_notify_auth_changed(struct wpa_supplicant *wpa_s)
226 {
227 	if (wpa_s->p2p_mgmt)
228 		return;
229 
230 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_AUTH_MODE);
231 }
232 
233 
wpas_notify_network_enabled_changed(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)234 void wpas_notify_network_enabled_changed(struct wpa_supplicant *wpa_s,
235 					 struct wpa_ssid *ssid)
236 {
237 	if (wpa_s->p2p_mgmt)
238 		return;
239 
240 	wpas_dbus_signal_network_enabled_changed(wpa_s, ssid);
241 }
242 
243 
wpas_notify_network_selected(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)244 void wpas_notify_network_selected(struct wpa_supplicant *wpa_s,
245 				  struct wpa_ssid *ssid)
246 {
247 	if (wpa_s->p2p_mgmt)
248 		return;
249 
250 	wpas_dbus_signal_network_selected(wpa_s, ssid->id);
251 }
252 
253 
wpas_notify_network_request(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,enum wpa_ctrl_req_type rtype,const char * default_txt)254 void wpas_notify_network_request(struct wpa_supplicant *wpa_s,
255 				 struct wpa_ssid *ssid,
256 				 enum wpa_ctrl_req_type rtype,
257 				 const char *default_txt)
258 {
259 	if (wpa_s->p2p_mgmt)
260 		return;
261 
262 	wpas_dbus_signal_network_request(wpa_s, ssid, rtype, default_txt);
263 }
264 
265 
wpas_notify_scanning(struct wpa_supplicant * wpa_s)266 void wpas_notify_scanning(struct wpa_supplicant *wpa_s)
267 {
268 	if (wpa_s->p2p_mgmt)
269 		return;
270 
271 	/* notify the new DBus API */
272 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SCANNING);
273 }
274 
275 
wpas_notify_scan_done(struct wpa_supplicant * wpa_s,int success)276 void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success)
277 {
278 	if (wpa_s->p2p_mgmt)
279 		return;
280 
281 	wpas_dbus_signal_scan_done(wpa_s, success);
282 }
283 
284 
wpas_notify_scan_results(struct wpa_supplicant * wpa_s)285 void wpas_notify_scan_results(struct wpa_supplicant *wpa_s)
286 {
287 	if (wpa_s->p2p_mgmt)
288 		return;
289 
290 	wpas_wps_notify_scan_results(wpa_s);
291 }
292 
293 
wpas_notify_wps_credential(struct wpa_supplicant * wpa_s,const struct wps_credential * cred)294 void wpas_notify_wps_credential(struct wpa_supplicant *wpa_s,
295 				const struct wps_credential *cred)
296 {
297 	if (wpa_s->p2p_mgmt)
298 		return;
299 
300 #ifdef CONFIG_WPS
301 	/* notify the new DBus API */
302 	wpas_dbus_signal_wps_cred(wpa_s, cred);
303 #endif /* CONFIG_WPS */
304 }
305 
306 
wpas_notify_wps_event_m2d(struct wpa_supplicant * wpa_s,struct wps_event_m2d * m2d)307 void wpas_notify_wps_event_m2d(struct wpa_supplicant *wpa_s,
308 			       struct wps_event_m2d *m2d)
309 {
310 	if (wpa_s->p2p_mgmt)
311 		return;
312 
313 #ifdef CONFIG_WPS
314 	wpas_dbus_signal_wps_event_m2d(wpa_s, m2d);
315 #endif /* CONFIG_WPS */
316 }
317 
318 
wpas_notify_wps_event_fail(struct wpa_supplicant * wpa_s,struct wps_event_fail * fail)319 void wpas_notify_wps_event_fail(struct wpa_supplicant *wpa_s,
320 				struct wps_event_fail *fail)
321 {
322 	if (wpa_s->p2p_mgmt)
323 		return;
324 
325 #ifdef CONFIG_WPS
326 	wpas_dbus_signal_wps_event_fail(wpa_s, fail);
327 #endif /* CONFIG_WPS */
328 }
329 
330 
wpas_notify_wps_event_success(struct wpa_supplicant * wpa_s)331 void wpas_notify_wps_event_success(struct wpa_supplicant *wpa_s)
332 {
333 	if (wpa_s->p2p_mgmt)
334 		return;
335 
336 #ifdef CONFIG_WPS
337 	wpas_dbus_signal_wps_event_success(wpa_s);
338 #endif /* CONFIG_WPS */
339 }
340 
wpas_notify_wps_event_pbc_overlap(struct wpa_supplicant * wpa_s)341 void wpas_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
342 {
343 	if (wpa_s->p2p_mgmt)
344 		return;
345 
346 #ifdef CONFIG_WPS
347 	wpas_dbus_signal_wps_event_pbc_overlap(wpa_s);
348 #endif /* CONFIG_WPS */
349 }
350 
351 
wpas_notify_network_added(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)352 void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
353 			       struct wpa_ssid *ssid)
354 {
355 	if (wpa_s->p2p_mgmt)
356 		return;
357 
358 	/*
359 	 * Networks objects created during any P2P activities should not be
360 	 * exposed out. They might/will confuse certain non-P2P aware
361 	 * applications since these network objects won't behave like
362 	 * regular ones.
363 	 */
364 	if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s) {
365 		wpas_dbus_register_network(wpa_s, ssid);
366 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_NETWORK_ADDED "%d",
367 			     ssid->id);
368 	}
369 }
370 
371 
wpas_notify_persistent_group_added(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)372 void wpas_notify_persistent_group_added(struct wpa_supplicant *wpa_s,
373 					struct wpa_ssid *ssid)
374 {
375 #ifdef CONFIG_P2P
376 	wpas_dbus_register_persistent_group(wpa_s, ssid);
377 #endif /* CONFIG_P2P */
378 }
379 
380 
wpas_notify_persistent_group_removed(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)381 void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s,
382 					  struct wpa_ssid *ssid)
383 {
384 #ifdef CONFIG_P2P
385 	wpas_dbus_unregister_persistent_group(wpa_s, ssid->id);
386 #endif /* CONFIG_P2P */
387 }
388 
389 
wpas_notify_network_removed(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)390 void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
391 				 struct wpa_ssid *ssid)
392 {
393 	if (wpa_s->next_ssid == ssid)
394 		wpa_s->next_ssid = NULL;
395 	if (wpa_s->last_ssid == ssid)
396 		wpa_s->last_ssid = NULL;
397 	if (wpa_s->current_ssid == ssid)
398 		wpa_s->current_ssid = NULL;
399 	if (wpa_s->ml_connect_probe_ssid == ssid) {
400 		wpa_s->ml_connect_probe_ssid = NULL;
401 		wpa_s->ml_connect_probe_bss = NULL;
402 	}
403 	if (wpa_s->connect_without_scan == ssid)
404 		wpa_s->connect_without_scan = NULL;
405 #if defined(CONFIG_SME) && defined(CONFIG_SAE)
406 	if (wpa_s->sme.ext_auth_wpa_ssid == ssid)
407 		wpa_s->sme.ext_auth_wpa_ssid = NULL;
408 #endif /* CONFIG_SME && CONFIG_SAE */
409 	if (wpa_s->wpa) {
410 		if ((wpa_key_mgmt_sae(ssid->key_mgmt) &&
411 		     (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_STA)) ||
412 		    ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
413 		     (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_OWE_OFFLOAD_STA))) {
414 			/* For cases when PMK is generated at the driver */
415 			struct wpa_pmkid_params params;
416 
417 			os_memset(&params, 0, sizeof(params));
418 			params.ssid = ssid->ssid;
419 			params.ssid_len = ssid->ssid_len;
420 			wpa_drv_remove_pmkid(wpa_s, &params);
421 		}
422 		wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
423 	}
424 	if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s &&
425 	    !wpa_s->p2p_mgmt) {
426 		wpas_dbus_unregister_network(wpa_s, ssid->id);
427 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_NETWORK_REMOVED "%d",
428 			     ssid->id);
429 	}
430 	if (network_is_persistent_group(ssid))
431 		wpas_notify_persistent_group_removed(wpa_s, ssid);
432 
433 	wpas_p2p_network_removed(wpa_s, ssid);
434 }
435 
436 
wpas_notify_bss_added(struct wpa_supplicant * wpa_s,u8 bssid[],unsigned int id)437 void wpas_notify_bss_added(struct wpa_supplicant *wpa_s,
438 			   u8 bssid[], unsigned int id)
439 {
440 	if (wpa_s->p2p_mgmt)
441 		return;
442 
443 	wpas_dbus_register_bss(wpa_s, bssid, id);
444 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_BSS_ADDED "%u " MACSTR,
445 		     id, MAC2STR(bssid));
446 }
447 
448 
wpas_notify_bss_removed(struct wpa_supplicant * wpa_s,u8 bssid[],unsigned int id)449 void wpas_notify_bss_removed(struct wpa_supplicant *wpa_s,
450 			     u8 bssid[], unsigned int id)
451 {
452 	if (wpa_s->p2p_mgmt)
453 		return;
454 
455 	wpas_dbus_unregister_bss(wpa_s, bssid, id);
456 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_BSS_REMOVED "%u " MACSTR,
457 		     id, MAC2STR(bssid));
458 }
459 
460 
wpas_notify_bss_freq_changed(struct wpa_supplicant * wpa_s,unsigned int id)461 void wpas_notify_bss_freq_changed(struct wpa_supplicant *wpa_s,
462 				  unsigned int id)
463 {
464 	if (wpa_s->p2p_mgmt)
465 		return;
466 
467 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_FREQ, id);
468 }
469 
470 
wpas_notify_bss_signal_changed(struct wpa_supplicant * wpa_s,unsigned int id)471 void wpas_notify_bss_signal_changed(struct wpa_supplicant *wpa_s,
472 				    unsigned int id)
473 {
474 	if (wpa_s->p2p_mgmt)
475 		return;
476 
477 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_SIGNAL,
478 					  id);
479 }
480 
481 
wpas_notify_bss_privacy_changed(struct wpa_supplicant * wpa_s,unsigned int id)482 void wpas_notify_bss_privacy_changed(struct wpa_supplicant *wpa_s,
483 				     unsigned int id)
484 {
485 	if (wpa_s->p2p_mgmt)
486 		return;
487 
488 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_PRIVACY,
489 					  id);
490 }
491 
492 
wpas_notify_bss_mode_changed(struct wpa_supplicant * wpa_s,unsigned int id)493 void wpas_notify_bss_mode_changed(struct wpa_supplicant *wpa_s,
494 				  unsigned int id)
495 {
496 	if (wpa_s->p2p_mgmt)
497 		return;
498 
499 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_MODE, id);
500 }
501 
502 
wpas_notify_bss_wpaie_changed(struct wpa_supplicant * wpa_s,unsigned int id)503 void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s,
504 				   unsigned int id)
505 {
506 	if (wpa_s->p2p_mgmt)
507 		return;
508 
509 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPA, id);
510 }
511 
512 
wpas_notify_bss_rsnie_changed(struct wpa_supplicant * wpa_s,unsigned int id)513 void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s,
514 				   unsigned int id)
515 {
516 	if (wpa_s->p2p_mgmt)
517 		return;
518 
519 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RSN, id);
520 }
521 
522 
wpas_notify_bss_wps_changed(struct wpa_supplicant * wpa_s,unsigned int id)523 void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s,
524 				 unsigned int id)
525 {
526 	if (wpa_s->p2p_mgmt)
527 		return;
528 
529 #ifdef CONFIG_WPS
530 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPS, id);
531 #endif /* CONFIG_WPS */
532 }
533 
534 
wpas_notify_bss_ies_changed(struct wpa_supplicant * wpa_s,unsigned int id)535 void wpas_notify_bss_ies_changed(struct wpa_supplicant *wpa_s,
536 				   unsigned int id)
537 {
538 	if (wpa_s->p2p_mgmt)
539 		return;
540 
541 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_IES, id);
542 }
543 
544 
wpas_notify_bss_rates_changed(struct wpa_supplicant * wpa_s,unsigned int id)545 void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s,
546 				   unsigned int id)
547 {
548 	if (wpa_s->p2p_mgmt)
549 		return;
550 
551 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RATES, id);
552 }
553 
554 
wpas_notify_bss_seen(struct wpa_supplicant * wpa_s,unsigned int id)555 void wpas_notify_bss_seen(struct wpa_supplicant *wpa_s, unsigned int id)
556 {
557 	if (wpa_s->p2p_mgmt)
558 		return;
559 
560 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_AGE, id);
561 }
562 
563 
wpas_notify_bss_anqp_changed(struct wpa_supplicant * wpa_s,unsigned int id)564 void wpas_notify_bss_anqp_changed(struct wpa_supplicant *wpa_s, unsigned int id)
565 {
566 	if (wpa_s->p2p_mgmt)
567 		return;
568 
569 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_ANQP, id);
570 }
571 
572 
wpas_notify_blob_added(struct wpa_supplicant * wpa_s,const char * name)573 void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name)
574 {
575 	if (wpa_s->p2p_mgmt)
576 		return;
577 
578 	wpas_dbus_signal_blob_added(wpa_s, name);
579 }
580 
581 
wpas_notify_blob_removed(struct wpa_supplicant * wpa_s,const char * name)582 void wpas_notify_blob_removed(struct wpa_supplicant *wpa_s, const char *name)
583 {
584 	if (wpa_s->p2p_mgmt)
585 		return;
586 
587 	wpas_dbus_signal_blob_removed(wpa_s, name);
588 }
589 
590 
wpas_notify_debug_level_changed(struct wpa_global * global)591 void wpas_notify_debug_level_changed(struct wpa_global *global)
592 {
593 	wpas_dbus_signal_debug_level_changed(global);
594 }
595 
596 
wpas_notify_debug_timestamp_changed(struct wpa_global * global)597 void wpas_notify_debug_timestamp_changed(struct wpa_global *global)
598 {
599 	wpas_dbus_signal_debug_timestamp_changed(global);
600 }
601 
602 
wpas_notify_debug_show_keys_changed(struct wpa_global * global)603 void wpas_notify_debug_show_keys_changed(struct wpa_global *global)
604 {
605 	wpas_dbus_signal_debug_show_keys_changed(global);
606 }
607 
608 
wpas_notify_suspend(struct wpa_global * global)609 void wpas_notify_suspend(struct wpa_global *global)
610 {
611 	struct wpa_supplicant *wpa_s;
612 
613 	os_get_time(&global->suspend_time);
614 	wpa_printf(MSG_DEBUG, "System suspend notification");
615 	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
616 		wpa_drv_suspend(wpa_s);
617 }
618 
619 
wpas_notify_resume(struct wpa_global * global)620 void wpas_notify_resume(struct wpa_global *global)
621 {
622 	struct os_time now;
623 	int slept;
624 	struct wpa_supplicant *wpa_s;
625 
626 	if (global->suspend_time.sec == 0)
627 		slept = -1;
628 	else {
629 		os_get_time(&now);
630 		slept = now.sec - global->suspend_time.sec;
631 	}
632 	wpa_printf(MSG_DEBUG, "System resume notification (slept %d seconds)",
633 		   slept);
634 
635 	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
636 		wpa_drv_resume(wpa_s);
637 		if (wpa_s->wpa_state == WPA_DISCONNECTED)
638 			wpa_supplicant_req_scan(wpa_s, 0, 100000);
639 	}
640 }
641 
642 
643 #ifdef CONFIG_P2P
644 
wpas_notify_p2p_find_stopped(struct wpa_supplicant * wpa_s)645 void wpas_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s)
646 {
647 	/* Notify P2P find has stopped */
648 	wpas_dbus_signal_p2p_find_stopped(wpa_s);
649 }
650 
651 
wpas_notify_p2p_device_found(struct wpa_supplicant * wpa_s,const u8 * dev_addr,int new_device)652 void wpas_notify_p2p_device_found(struct wpa_supplicant *wpa_s,
653 				  const u8 *dev_addr, int new_device)
654 {
655 	if (new_device) {
656 		/* Create the new peer object */
657 		wpas_dbus_register_peer(wpa_s, dev_addr);
658 	}
659 
660 	/* Notify a new peer has been detected*/
661 	wpas_dbus_signal_peer_device_found(wpa_s, dev_addr);
662 }
663 
664 
wpas_notify_p2p_device_lost(struct wpa_supplicant * wpa_s,const u8 * dev_addr)665 void wpas_notify_p2p_device_lost(struct wpa_supplicant *wpa_s,
666 				 const u8 *dev_addr)
667 {
668 	wpas_dbus_unregister_peer(wpa_s, dev_addr);
669 
670 	/* Create signal on interface object*/
671 	wpas_dbus_signal_peer_device_lost(wpa_s, dev_addr);
672 }
673 
674 
wpas_notify_p2p_group_removed(struct wpa_supplicant * wpa_s,const struct wpa_ssid * ssid,const char * role)675 void wpas_notify_p2p_group_removed(struct wpa_supplicant *wpa_s,
676 				   const struct wpa_ssid *ssid,
677 				   const char *role)
678 {
679 	wpas_dbus_signal_p2p_group_removed(wpa_s, role);
680 
681 	wpas_dbus_unregister_p2p_group(wpa_s, ssid);
682 }
683 
684 
wpas_notify_p2p_go_neg_req(struct wpa_supplicant * wpa_s,const u8 * src,u16 dev_passwd_id,u8 go_intent)685 void wpas_notify_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
686 				const u8 *src, u16 dev_passwd_id, u8 go_intent)
687 {
688 	wpas_dbus_signal_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
689 }
690 
691 
wpas_notify_p2p_go_neg_completed(struct wpa_supplicant * wpa_s,struct p2p_go_neg_results * res)692 void wpas_notify_p2p_go_neg_completed(struct wpa_supplicant *wpa_s,
693 				      struct p2p_go_neg_results *res)
694 {
695 	wpas_dbus_signal_p2p_go_neg_resp(wpa_s, res);
696 }
697 
698 
wpas_notify_p2p_invitation_result(struct wpa_supplicant * wpa_s,int status,const u8 * bssid)699 void wpas_notify_p2p_invitation_result(struct wpa_supplicant *wpa_s,
700 				       int status, const u8 *bssid)
701 {
702 	wpas_dbus_signal_p2p_invitation_result(wpa_s, status, bssid);
703 }
704 
705 
wpas_notify_p2p_sd_request(struct wpa_supplicant * wpa_s,int freq,const u8 * sa,u8 dialog_token,u16 update_indic,const u8 * tlvs,size_t tlvs_len)706 void wpas_notify_p2p_sd_request(struct wpa_supplicant *wpa_s,
707 				int freq, const u8 *sa, u8 dialog_token,
708 				u16 update_indic, const u8 *tlvs,
709 				size_t tlvs_len)
710 {
711 	wpas_dbus_signal_p2p_sd_request(wpa_s, freq, sa, dialog_token,
712 					update_indic, tlvs, tlvs_len);
713 }
714 
715 
wpas_notify_p2p_sd_response(struct wpa_supplicant * wpa_s,const u8 * sa,u16 update_indic,const u8 * tlvs,size_t tlvs_len)716 void wpas_notify_p2p_sd_response(struct wpa_supplicant *wpa_s,
717 				 const u8 *sa, u16 update_indic,
718 				 const u8 *tlvs, size_t tlvs_len)
719 {
720 	wpas_dbus_signal_p2p_sd_response(wpa_s, sa, update_indic,
721 					 tlvs, tlvs_len);
722 }
723 
724 
725 /**
726  * wpas_notify_p2p_provision_discovery - Notification of provision discovery
727  * @dev_addr: Who sent the request or responded to our request.
728  * @request: Will be 1 if request, 0 for response.
729  * @status: Valid only in case of response (0 in case of success)
730  * @config_methods: WPS config methods
731  * @generated_pin: PIN to be displayed in case of WPS_CONFIG_DISPLAY method
732  *
733  * This can be used to notify:
734  * - Requests or responses
735  * - Various config methods
736  * - Failure condition in case of response
737  */
wpas_notify_p2p_provision_discovery(struct wpa_supplicant * wpa_s,const u8 * dev_addr,int request,enum p2p_prov_disc_status status,u16 config_methods,unsigned int generated_pin)738 void wpas_notify_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
739 					 const u8 *dev_addr, int request,
740 					 enum p2p_prov_disc_status status,
741 					 u16 config_methods,
742 					 unsigned int generated_pin)
743 {
744 	wpas_dbus_signal_p2p_provision_discovery(wpa_s, dev_addr, request,
745 						 status, config_methods,
746 						 generated_pin);
747 }
748 
749 
wpas_notify_p2p_group_started(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,int persistent,int client,const u8 * ip)750 void wpas_notify_p2p_group_started(struct wpa_supplicant *wpa_s,
751 				   struct wpa_ssid *ssid, int persistent,
752 				   int client, const u8 *ip)
753 {
754 	/* Notify a group has been started */
755 	wpas_dbus_register_p2p_group(wpa_s, ssid);
756 
757 	wpas_dbus_signal_p2p_group_started(wpa_s, client, persistent, ip);
758 }
759 
760 
wpas_notify_p2p_group_formation_failure(struct wpa_supplicant * wpa_s,const char * reason)761 void wpas_notify_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
762 					     const char *reason)
763 {
764 	/* Notify a group formation failed */
765 	wpas_dbus_signal_p2p_group_formation_failure(wpa_s, reason);
766 }
767 
768 
wpas_notify_p2p_wps_failed(struct wpa_supplicant * wpa_s,struct wps_event_fail * fail)769 void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s,
770 				struct wps_event_fail *fail)
771 {
772 	wpas_dbus_signal_p2p_wps_failed(wpa_s, fail);
773 }
774 
775 
wpas_notify_p2p_invitation_received(struct wpa_supplicant * wpa_s,const u8 * sa,const u8 * go_dev_addr,const u8 * bssid,int id,int op_freq)776 void wpas_notify_p2p_invitation_received(struct wpa_supplicant *wpa_s,
777 					 const u8 *sa, const u8 *go_dev_addr,
778 					 const u8 *bssid, int id, int op_freq)
779 {
780 	/* Notify a P2P Invitation Request */
781 	wpas_dbus_signal_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
782 						 id, op_freq);
783 }
784 
785 #endif /* CONFIG_P2P */
786 
787 
wpas_notify_ap_sta_authorized(struct wpa_supplicant * wpa_s,const u8 * sta,const u8 * p2p_dev_addr,const u8 * ip)788 static void wpas_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
789 					  const u8 *sta,
790 					  const u8 *p2p_dev_addr, const u8 *ip)
791 {
792 #ifdef CONFIG_P2P
793 	wpas_p2p_notify_ap_sta_authorized(wpa_s, p2p_dev_addr);
794 
795 	/*
796 	 * Create 'peer-joined' signal on group object -- will also
797 	 * check P2P itself.
798 	 */
799 	if (p2p_dev_addr)
800 		wpas_dbus_signal_p2p_peer_joined(wpa_s, p2p_dev_addr);
801 #endif /* CONFIG_P2P */
802 
803 	/* Register the station */
804 	wpas_dbus_register_sta(wpa_s, sta);
805 
806 	/* Notify listeners a new station has been authorized */
807 	wpas_dbus_signal_sta_authorized(wpa_s, sta);
808 }
809 
810 
wpas_notify_ap_sta_deauthorized(struct wpa_supplicant * wpa_s,const u8 * sta,const u8 * p2p_dev_addr)811 static void wpas_notify_ap_sta_deauthorized(struct wpa_supplicant *wpa_s,
812 					    const u8 *sta,
813 					    const u8 *p2p_dev_addr)
814 {
815 #ifdef CONFIG_P2P
816 	/*
817 	 * Create 'peer-disconnected' signal on group object if this
818 	 * is a P2P group.
819 	 */
820 	if (p2p_dev_addr)
821 		wpas_dbus_signal_p2p_peer_disconnected(wpa_s, p2p_dev_addr);
822 #endif /* CONFIG_P2P */
823 
824 	/* Notify listeners a station has been deauthorized */
825 	wpas_dbus_signal_sta_deauthorized(wpa_s, sta);
826 
827 	/* Unregister the station */
828 	wpas_dbus_unregister_sta(wpa_s, sta);
829 }
830 
831 
wpas_notify_sta_authorized(struct wpa_supplicant * wpa_s,const u8 * mac_addr,int authorized,const u8 * p2p_dev_addr,const u8 * ip)832 void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
833 				const u8 *mac_addr, int authorized,
834 				const u8 *p2p_dev_addr, const u8 *ip)
835 {
836 	if (authorized)
837 		wpas_notify_ap_sta_authorized(wpa_s, mac_addr, p2p_dev_addr,
838 					      ip);
839 	else
840 		wpas_notify_ap_sta_deauthorized(wpa_s, mac_addr, p2p_dev_addr);
841 }
842 
843 
wpas_notify_certification(struct wpa_supplicant * wpa_s,struct tls_cert_data * cert,const char * cert_hash)844 void wpas_notify_certification(struct wpa_supplicant *wpa_s,
845 			       struct tls_cert_data *cert,
846 			       const char *cert_hash)
847 {
848 	int i;
849 
850 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT
851 		"depth=%d subject='%s'%s%s%s%s",
852 		cert->depth, cert->subject, cert_hash ? " hash=" : "",
853 		cert_hash ? cert_hash : "",
854 		cert->tod == 2 ? " tod=2" : "",
855 		cert->tod == 1 ? " tod=1" : "");
856 
857 	if (cert->cert) {
858 		char *cert_hex;
859 		size_t len = wpabuf_len(cert->cert) * 2 + 1;
860 		cert_hex = os_malloc(len);
861 		if (cert_hex) {
862 			wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert->cert),
863 					 wpabuf_len(cert->cert));
864 			wpa_msg_ctrl(wpa_s, MSG_INFO,
865 				     WPA_EVENT_EAP_PEER_CERT
866 				     "depth=%d subject='%s' cert=%s",
867 				     cert->depth, cert->subject, cert_hex);
868 			os_free(cert_hex);
869 		}
870 	}
871 
872 	for (i = 0; i < cert->num_altsubject; i++)
873 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT
874 			"depth=%d %s", cert->depth, cert->altsubject[i]);
875 
876 	/* notify the new DBus API */
877 	wpas_dbus_signal_certification(wpa_s, cert->depth, cert->subject,
878 				       cert->altsubject, cert->num_altsubject,
879 				       cert_hash, cert->cert);
880 }
881 
882 
wpas_notify_preq(struct wpa_supplicant * wpa_s,const u8 * addr,const u8 * dst,const u8 * bssid,const u8 * ie,size_t ie_len,u32 ssi_signal)883 void wpas_notify_preq(struct wpa_supplicant *wpa_s,
884 		      const u8 *addr, const u8 *dst, const u8 *bssid,
885 		      const u8 *ie, size_t ie_len, u32 ssi_signal)
886 {
887 #ifdef CONFIG_AP
888 	wpas_dbus_signal_preq(wpa_s, addr, dst, bssid, ie, ie_len, ssi_signal);
889 #endif /* CONFIG_AP */
890 }
891 
892 
wpas_notify_eap_status(struct wpa_supplicant * wpa_s,const char * status,const char * parameter)893 void wpas_notify_eap_status(struct wpa_supplicant *wpa_s, const char *status,
894 			    const char *parameter)
895 {
896 	wpas_dbus_signal_eap_status(wpa_s, status, parameter);
897 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_EAP_STATUS
898 		     "status='%s' parameter='%s'",
899 		     status, parameter);
900 }
901 
902 
wpas_notify_eap_error(struct wpa_supplicant * wpa_s,int error_code)903 void wpas_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code)
904 {
905 	wpa_msg(wpa_s, MSG_ERROR, WPA_EVENT_EAP_ERROR_CODE "%d", error_code);
906 }
907 
908 
wpas_notify_psk_mismatch(struct wpa_supplicant * wpa_s)909 void wpas_notify_psk_mismatch(struct wpa_supplicant *wpa_s)
910 {
911 	wpas_dbus_signal_psk_mismatch(wpa_s);
912 }
913 
914 
wpas_notify_network_bssid_set_changed(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)915 void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s,
916 					   struct wpa_ssid *ssid)
917 {
918 	if (wpa_s->current_ssid != ssid)
919 		return;
920 
921 	wpa_dbg(wpa_s, MSG_DEBUG,
922 		"Network bssid config changed for the current network - within-ESS roaming %s",
923 		ssid->bssid_set ? "disabled" : "enabled");
924 
925 	wpa_drv_roaming(wpa_s, !ssid->bssid_set,
926 			ssid->bssid_set ? ssid->bssid : NULL);
927 }
928 
929 
wpas_notify_network_type_changed(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)930 void wpas_notify_network_type_changed(struct wpa_supplicant *wpa_s,
931 				      struct wpa_ssid *ssid)
932 {
933 #ifdef CONFIG_P2P
934 	if (ssid->disabled == 2) {
935 		/* Changed from normal network profile to persistent group */
936 		ssid->disabled = 0;
937 		wpas_dbus_unregister_network(wpa_s, ssid->id);
938 		ssid->disabled = 2;
939 		ssid->p2p_persistent_group = 1;
940 		wpas_dbus_register_persistent_group(wpa_s, ssid);
941 	} else {
942 		/* Changed from persistent group to normal network profile */
943 		wpas_dbus_unregister_persistent_group(wpa_s, ssid->id);
944 		ssid->p2p_persistent_group = 0;
945 		wpas_dbus_register_network(wpa_s, ssid);
946 	}
947 #endif /* CONFIG_P2P */
948 }
949 
950 
951 #ifdef CONFIG_MESH
952 
wpas_notify_mesh_group_started(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)953 void wpas_notify_mesh_group_started(struct wpa_supplicant *wpa_s,
954 				    struct wpa_ssid *ssid)
955 {
956 	if (wpa_s->p2p_mgmt)
957 		return;
958 
959 	wpas_dbus_signal_mesh_group_started(wpa_s, ssid);
960 }
961 
962 
wpas_notify_mesh_group_removed(struct wpa_supplicant * wpa_s,const u8 * meshid,u8 meshid_len,u16 reason_code)963 void wpas_notify_mesh_group_removed(struct wpa_supplicant *wpa_s,
964 				    const u8 *meshid, u8 meshid_len,
965 				    u16 reason_code)
966 {
967 	if (wpa_s->p2p_mgmt)
968 		return;
969 
970 	wpas_dbus_signal_mesh_group_removed(wpa_s, meshid, meshid_len,
971 					    reason_code);
972 }
973 
974 
wpas_notify_mesh_peer_connected(struct wpa_supplicant * wpa_s,const u8 * peer_addr)975 void wpas_notify_mesh_peer_connected(struct wpa_supplicant *wpa_s,
976 				     const u8 *peer_addr)
977 {
978 	if (wpa_s->p2p_mgmt)
979 		return;
980 
981 	wpa_msg(wpa_s, MSG_INFO, MESH_PEER_CONNECTED MACSTR,
982 		MAC2STR(peer_addr));
983 	wpas_dbus_signal_mesh_peer_connected(wpa_s, peer_addr);
984 }
985 
986 
wpas_notify_mesh_peer_disconnected(struct wpa_supplicant * wpa_s,const u8 * peer_addr,u16 reason_code)987 void wpas_notify_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
988 					const u8 *peer_addr, u16 reason_code)
989 {
990 	if (wpa_s->p2p_mgmt)
991 		return;
992 
993 	wpa_msg(wpa_s, MSG_INFO, MESH_PEER_DISCONNECTED MACSTR,
994 		MAC2STR(peer_addr));
995 	wpas_dbus_signal_mesh_peer_disconnected(wpa_s, peer_addr, reason_code);
996 }
997 
998 #endif /* CONFIG_MESH */
999 
1000 
1001 #ifdef CONFIG_INTERWORKING
1002 
wpas_notify_interworking_ap_added(struct wpa_supplicant * wpa_s,struct wpa_bss * bss,struct wpa_cred * cred,int excluded,const char * type,int bh,int bss_load,int conn_capab)1003 void wpas_notify_interworking_ap_added(struct wpa_supplicant *wpa_s,
1004 				       struct wpa_bss *bss,
1005 				       struct wpa_cred *cred, int excluded,
1006 				       const char *type, int bh, int bss_load,
1007 				       int conn_capab)
1008 {
1009 	wpa_msg(wpa_s, MSG_INFO, "%s" MACSTR " type=%s%s%s%s id=%d priority=%d sp_priority=%d",
1010 		excluded ? INTERWORKING_EXCLUDED : INTERWORKING_AP,
1011 		MAC2STR(bss->bssid), type,
1012 		bh ? " below_min_backhaul=1" : "",
1013 		bss_load ? " over_max_bss_load=1" : "",
1014 		conn_capab ? " conn_capab_missing=1" : "",
1015 		cred->id, cred->priority, cred->sp_priority);
1016 
1017 	wpas_dbus_signal_interworking_ap_added(wpa_s, bss, cred, type, excluded,
1018 					       bh, bss_load, conn_capab);
1019 }
1020 
1021 
wpas_notify_interworking_select_done(struct wpa_supplicant * wpa_s)1022 void wpas_notify_interworking_select_done(struct wpa_supplicant *wpa_s)
1023 {
1024 	wpas_dbus_signal_interworking_select_done(wpa_s);
1025 }
1026 
1027 
wpas_notify_anqp_query_done(struct wpa_supplicant * wpa_s,const u8 * dst,const char * result)1028 void wpas_notify_anqp_query_done(struct wpa_supplicant *wpa_s,
1029 				 const u8 *dst, const char *result)
1030 {
1031 	wpa_msg(wpa_s, MSG_INFO, ANQP_QUERY_DONE "addr=" MACSTR " result=%s",
1032 		MAC2STR(dst), result);
1033 
1034 	wpas_dbus_signal_anqp_query_done(wpa_s, dst, result);
1035 }
1036 
1037 #endif /* CONFIG_INTERWORKING */
1038 
1039 
wpas_notify_pmk_cache_added(struct wpa_supplicant * wpa_s,struct rsn_pmksa_cache_entry * entry)1040 void wpas_notify_pmk_cache_added(struct wpa_supplicant *wpa_s,
1041 				 struct rsn_pmksa_cache_entry *entry)
1042 {
1043 	/* TODO: Notify external entities of the added PMKSA cache entry */
1044 }
1045 
1046 
wpas_notify_signal_change(struct wpa_supplicant * wpa_s)1047 void wpas_notify_signal_change(struct wpa_supplicant *wpa_s)
1048 {
1049 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SIGNAL_CHANGE);
1050 }
1051 
1052 
1053 #ifdef CONFIG_HS20
wpas_notify_hs20_t_c_acceptance(struct wpa_supplicant * wpa_s,const char * url)1054 void wpas_notify_hs20_t_c_acceptance(struct wpa_supplicant *wpa_s,
1055 				     const char *url)
1056 {
1057 	wpa_msg(wpa_s, MSG_INFO, HS20_T_C_ACCEPTANCE "%s", url);
1058 	wpas_dbus_signal_hs20_t_c_acceptance(wpa_s, url);
1059 }
1060 #endif /* CONFIG_HS20 */
1061