Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * wpa_supplicant - Event notifications
      3  * Copyright (c) 2009-2010, Jouni Malinen <j (at) 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 "dbus/dbus_common.h"
     17 #include "dbus/dbus_old.h"
     18 #include "dbus/dbus_new.h"
     19 #include "rsn_supp/wpa.h"
     20 #include "driver_i.h"
     21 #include "scan.h"
     22 #include "p2p_supplicant.h"
     23 #include "sme.h"
     24 #include "notify.h"
     25 
     26 int wpas_notify_supplicant_initialized(struct wpa_global *global)
     27 {
     28 #ifdef CONFIG_DBUS
     29 	if (global->params.dbus_ctrl_interface) {
     30 		global->dbus = wpas_dbus_init(global);
     31 		if (global->dbus == NULL)
     32 			return -1;
     33 	}
     34 #endif /* CONFIG_DBUS */
     35 
     36 	return 0;
     37 }
     38 
     39 
     40 void wpas_notify_supplicant_deinitialized(struct wpa_global *global)
     41 {
     42 #ifdef CONFIG_DBUS
     43 	if (global->dbus)
     44 		wpas_dbus_deinit(global->dbus);
     45 #endif /* CONFIG_DBUS */
     46 }
     47 
     48 
     49 int wpas_notify_iface_added(struct wpa_supplicant *wpa_s)
     50 {
     51 	if (wpas_dbus_register_iface(wpa_s))
     52 		return -1;
     53 
     54 	if (wpas_dbus_register_interface(wpa_s))
     55 		return -1;
     56 
     57 	return 0;
     58 }
     59 
     60 
     61 void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s)
     62 {
     63 	/* unregister interface in old DBus ctrl iface */
     64 	wpas_dbus_unregister_iface(wpa_s);
     65 
     66 	/* unregister interface in new DBus ctrl iface */
     67 	wpas_dbus_unregister_interface(wpa_s);
     68 }
     69 
     70 
     71 void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
     72 			       enum wpa_states new_state,
     73 			       enum wpa_states old_state)
     74 {
     75 	/* notify the old DBus API */
     76 	wpa_supplicant_dbus_notify_state_change(wpa_s, new_state,
     77 						old_state);
     78 
     79 	/* notify the new DBus API */
     80 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATE);
     81 
     82 #ifdef CONFIG_P2P
     83 	if (new_state == WPA_COMPLETED)
     84 		wpas_p2p_notif_connected(wpa_s);
     85 	else if (new_state < WPA_ASSOCIATED)
     86 		wpas_p2p_notif_disconnected(wpa_s);
     87 #endif /* CONFIG_P2P */
     88 
     89 	sme_state_changed(wpa_s);
     90 
     91 #ifdef ANDROID
     92 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_STATE_CHANGE
     93 		     "id=%d state=%d BSSID=" MACSTR " SSID=%s",
     94 		     wpa_s->current_ssid ? wpa_s->current_ssid->id : -1,
     95 		     new_state,
     96 		     MAC2STR(wpa_s->pending_bssid),
     97 		     wpa_s->current_ssid && wpa_s->current_ssid->ssid ?
     98 		     wpa_ssid_txt(wpa_s->current_ssid->ssid,
     99 		     wpa_s->current_ssid->ssid_len): "");
    100 #endif /* ANDROID */
    101 }
    102 
    103 
    104 void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)
    105 {
    106 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_NETWORK);
    107 }
    108 
    109 
    110 void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s)
    111 {
    112 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_AP_SCAN);
    113 }
    114 
    115 
    116 void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s)
    117 {
    118 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_BSS);
    119 }
    120 
    121 
    122 void wpas_notify_auth_changed(struct wpa_supplicant *wpa_s)
    123 {
    124 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_AUTH_MODE);
    125 }
    126 
    127 
    128 void wpas_notify_network_enabled_changed(struct wpa_supplicant *wpa_s,
    129 					 struct wpa_ssid *ssid)
    130 {
    131 	wpas_dbus_signal_network_enabled_changed(wpa_s, ssid);
    132 }
    133 
    134 
    135 void wpas_notify_network_selected(struct wpa_supplicant *wpa_s,
    136 				  struct wpa_ssid *ssid)
    137 {
    138 	wpas_dbus_signal_network_selected(wpa_s, ssid->id);
    139 }
    140 
    141 
    142 void wpas_notify_network_request(struct wpa_supplicant *wpa_s,
    143 				 struct wpa_ssid *ssid,
    144 				 enum wpa_ctrl_req_type rtype,
    145 				 const char *default_txt)
    146 {
    147 	wpas_dbus_signal_network_request(wpa_s, ssid, rtype, default_txt);
    148 }
    149 
    150 
    151 void wpas_notify_scanning(struct wpa_supplicant *wpa_s)
    152 {
    153 	/* notify the old DBus API */
    154 	wpa_supplicant_dbus_notify_scanning(wpa_s);
    155 
    156 	/* notify the new DBus API */
    157 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SCANNING);
    158 }
    159 
    160 
    161 void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success)
    162 {
    163 	wpas_dbus_signal_scan_done(wpa_s, success);
    164 }
    165 
    166 
    167 void wpas_notify_scan_results(struct wpa_supplicant *wpa_s)
    168 {
    169 	/* notify the old DBus API */
    170 	wpa_supplicant_dbus_notify_scan_results(wpa_s);
    171 
    172 	wpas_wps_notify_scan_results(wpa_s);
    173 }
    174 
    175 
    176 void wpas_notify_wps_credential(struct wpa_supplicant *wpa_s,
    177 				const struct wps_credential *cred)
    178 {
    179 #ifdef CONFIG_WPS
    180 	/* notify the old DBus API */
    181 	wpa_supplicant_dbus_notify_wps_cred(wpa_s, cred);
    182 	/* notify the new DBus API */
    183 	wpas_dbus_signal_wps_cred(wpa_s, cred);
    184 #endif /* CONFIG_WPS */
    185 }
    186 
    187 
    188 void wpas_notify_wps_event_m2d(struct wpa_supplicant *wpa_s,
    189 			       struct wps_event_m2d *m2d)
    190 {
    191 #ifdef CONFIG_WPS
    192 	wpas_dbus_signal_wps_event_m2d(wpa_s, m2d);
    193 #endif /* CONFIG_WPS */
    194 }
    195 
    196 
    197 void wpas_notify_wps_event_fail(struct wpa_supplicant *wpa_s,
    198 				struct wps_event_fail *fail)
    199 {
    200 #ifdef CONFIG_WPS
    201 	wpas_dbus_signal_wps_event_fail(wpa_s, fail);
    202 #endif /* CONFIG_WPS */
    203 }
    204 
    205 
    206 void wpas_notify_wps_event_success(struct wpa_supplicant *wpa_s)
    207 {
    208 #ifdef CONFIG_WPS
    209 	wpas_dbus_signal_wps_event_success(wpa_s);
    210 #endif /* CONFIG_WPS */
    211 }
    212 
    213 
    214 void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
    215 			       struct wpa_ssid *ssid)
    216 {
    217 	/*
    218 	 * Networks objects created during any P2P activities should not be
    219 	 * exposed out. They might/will confuse certain non-P2P aware
    220 	 * applications since these network objects won't behave like
    221 	 * regular ones.
    222 	 */
    223 	if (wpa_s->global->p2p_group_formation != wpa_s)
    224 		wpas_dbus_register_network(wpa_s, ssid);
    225 }
    226 
    227 
    228 void wpas_notify_persistent_group_added(struct wpa_supplicant *wpa_s,
    229 					struct wpa_ssid *ssid)
    230 {
    231 #ifdef CONFIG_P2P
    232 	wpas_dbus_register_persistent_group(wpa_s, ssid);
    233 #endif /* CONFIG_P2P */
    234 }
    235 
    236 
    237 void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s,
    238 					  struct wpa_ssid *ssid)
    239 {
    240 #ifdef CONFIG_P2P
    241 	wpas_dbus_unregister_persistent_group(wpa_s, ssid->id);
    242 #endif /* CONFIG_P2P */
    243 }
    244 
    245 
    246 void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
    247 				 struct wpa_ssid *ssid)
    248 {
    249 	if (wpa_s->wpa)
    250 		wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
    251 	if (wpa_s->global->p2p_group_formation != wpa_s)
    252 		wpas_dbus_unregister_network(wpa_s, ssid->id);
    253 #ifdef CONFIG_P2P
    254 	wpas_p2p_network_removed(wpa_s, ssid);
    255 #endif /* CONFIG_P2P */
    256 }
    257 
    258 
    259 void wpas_notify_bss_added(struct wpa_supplicant *wpa_s,
    260 			   u8 bssid[], unsigned int id)
    261 {
    262 	wpas_dbus_register_bss(wpa_s, bssid, id);
    263 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_BSS_ADDED "%u " MACSTR,
    264 		     id, MAC2STR(bssid));
    265 }
    266 
    267 
    268 void wpas_notify_bss_removed(struct wpa_supplicant *wpa_s,
    269 			     u8 bssid[], unsigned int id)
    270 {
    271 	wpas_dbus_unregister_bss(wpa_s, bssid, id);
    272 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_BSS_REMOVED "%u " MACSTR,
    273 		     id, MAC2STR(bssid));
    274 }
    275 
    276 
    277 void wpas_notify_bss_freq_changed(struct wpa_supplicant *wpa_s,
    278 				  unsigned int id)
    279 {
    280 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_FREQ, id);
    281 }
    282 
    283 
    284 void wpas_notify_bss_signal_changed(struct wpa_supplicant *wpa_s,
    285 				    unsigned int id)
    286 {
    287 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_SIGNAL,
    288 					  id);
    289 }
    290 
    291 
    292 void wpas_notify_bss_privacy_changed(struct wpa_supplicant *wpa_s,
    293 				     unsigned int id)
    294 {
    295 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_PRIVACY,
    296 					  id);
    297 }
    298 
    299 
    300 void wpas_notify_bss_mode_changed(struct wpa_supplicant *wpa_s,
    301 				  unsigned int id)
    302 {
    303 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_MODE, id);
    304 }
    305 
    306 
    307 void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s,
    308 				   unsigned int id)
    309 {
    310 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPA, id);
    311 }
    312 
    313 
    314 void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s,
    315 				   unsigned int id)
    316 {
    317 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RSN, id);
    318 }
    319 
    320 
    321 void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s,
    322 				 unsigned int id)
    323 {
    324 }
    325 
    326 
    327 void wpas_notify_bss_ies_changed(struct wpa_supplicant *wpa_s,
    328 				   unsigned int id)
    329 {
    330 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_IES, id);
    331 }
    332 
    333 
    334 void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s,
    335 				   unsigned int id)
    336 {
    337 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RATES, id);
    338 }
    339 
    340 
    341 void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name)
    342 {
    343 	wpas_dbus_signal_blob_added(wpa_s, name);
    344 }
    345 
    346 
    347 void wpas_notify_blob_removed(struct wpa_supplicant *wpa_s, const char *name)
    348 {
    349 	wpas_dbus_signal_blob_removed(wpa_s, name);
    350 }
    351 
    352 
    353 void wpas_notify_debug_level_changed(struct wpa_global *global)
    354 {
    355 	wpas_dbus_signal_debug_level_changed(global);
    356 }
    357 
    358 
    359 void wpas_notify_debug_timestamp_changed(struct wpa_global *global)
    360 {
    361 	wpas_dbus_signal_debug_timestamp_changed(global);
    362 }
    363 
    364 
    365 void wpas_notify_debug_show_keys_changed(struct wpa_global *global)
    366 {
    367 	wpas_dbus_signal_debug_show_keys_changed(global);
    368 }
    369 
    370 
    371 void wpas_notify_suspend(struct wpa_global *global)
    372 {
    373 	struct wpa_supplicant *wpa_s;
    374 
    375 	os_get_time(&global->suspend_time);
    376 	wpa_printf(MSG_DEBUG, "System suspend notification");
    377 	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
    378 		wpa_drv_suspend(wpa_s);
    379 }
    380 
    381 
    382 void wpas_notify_resume(struct wpa_global *global)
    383 {
    384 	struct os_time now;
    385 	int slept;
    386 	struct wpa_supplicant *wpa_s;
    387 
    388 	if (global->suspend_time.sec == 0)
    389 		slept = -1;
    390 	else {
    391 		os_get_time(&now);
    392 		slept = now.sec - global->suspend_time.sec;
    393 	}
    394 	wpa_printf(MSG_DEBUG, "System resume notification (slept %d seconds)",
    395 		   slept);
    396 
    397 	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    398 		wpa_drv_resume(wpa_s);
    399 		if (wpa_s->wpa_state == WPA_DISCONNECTED)
    400 			wpa_supplicant_req_scan(wpa_s, 0, 100000);
    401 	}
    402 }
    403 
    404 
    405 #ifdef CONFIG_P2P
    406 
    407 void wpas_notify_p2p_device_found(struct wpa_supplicant *wpa_s,
    408 				  const u8 *dev_addr, int new_device)
    409 {
    410 	if (new_device) {
    411 		/* Create the new peer object */
    412 		wpas_dbus_register_peer(wpa_s, dev_addr);
    413 	}
    414 
    415 	/* Notify a new peer has been detected*/
    416 	wpas_dbus_signal_peer_device_found(wpa_s, dev_addr);
    417 }
    418 
    419 
    420 void wpas_notify_p2p_device_lost(struct wpa_supplicant *wpa_s,
    421 				 const u8 *dev_addr)
    422 {
    423 	wpas_dbus_unregister_peer(wpa_s, dev_addr);
    424 
    425 	/* Create signal on interface object*/
    426 	wpas_dbus_signal_peer_device_lost(wpa_s, dev_addr);
    427 }
    428 
    429 
    430 void wpas_notify_p2p_group_removed(struct wpa_supplicant *wpa_s,
    431 				   const struct wpa_ssid *ssid,
    432 				   const char *role)
    433 {
    434 	wpas_dbus_unregister_p2p_group(wpa_s, ssid);
    435 
    436 	wpas_dbus_signal_p2p_group_removed(wpa_s, role);
    437 }
    438 
    439 
    440 void wpas_notify_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
    441 				const u8 *src, u16 dev_passwd_id)
    442 {
    443 	wpas_dbus_signal_p2p_go_neg_req(wpa_s, src, dev_passwd_id);
    444 }
    445 
    446 
    447 void wpas_notify_p2p_go_neg_completed(struct wpa_supplicant *wpa_s,
    448 				      struct p2p_go_neg_results *res)
    449 {
    450 	wpas_dbus_signal_p2p_go_neg_resp(wpa_s, res);
    451 }
    452 
    453 
    454 void wpas_notify_p2p_invitation_result(struct wpa_supplicant *wpa_s,
    455 				       int status, const u8 *bssid)
    456 {
    457 	wpas_dbus_signal_p2p_invitation_result(wpa_s, status, bssid);
    458 }
    459 
    460 
    461 void wpas_notify_p2p_sd_request(struct wpa_supplicant *wpa_s,
    462 				int freq, const u8 *sa, u8 dialog_token,
    463 				u16 update_indic, const u8 *tlvs,
    464 				size_t tlvs_len)
    465 {
    466 	wpas_dbus_signal_p2p_sd_request(wpa_s, freq, sa, dialog_token,
    467 					update_indic, tlvs, tlvs_len);
    468 }
    469 
    470 
    471 void wpas_notify_p2p_sd_response(struct wpa_supplicant *wpa_s,
    472 				 const u8 *sa, u16 update_indic,
    473 				 const u8 *tlvs, size_t tlvs_len)
    474 {
    475 	wpas_dbus_signal_p2p_sd_response(wpa_s, sa, update_indic,
    476 					 tlvs, tlvs_len);
    477 }
    478 
    479 
    480 /**
    481  * wpas_notify_p2p_provision_discovery - Notification of provision discovery
    482  * @dev_addr: Who sent the request or responded to our request.
    483  * @request: Will be 1 if request, 0 for response.
    484  * @status: Valid only in case of response (0 in case of success)
    485  * @config_methods: WPS config methods
    486  * @generated_pin: PIN to be displayed in case of WPS_CONFIG_DISPLAY method
    487  *
    488  * This can be used to notify:
    489  * - Requests or responses
    490  * - Various config methods
    491  * - Failure condition in case of response
    492  */
    493 void wpas_notify_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
    494 					 const u8 *dev_addr, int request,
    495 					 enum p2p_prov_disc_status status,
    496 					 u16 config_methods,
    497 					 unsigned int generated_pin)
    498 {
    499 	wpas_dbus_signal_p2p_provision_discovery(wpa_s, dev_addr, request,
    500 						 status, config_methods,
    501 						 generated_pin);
    502 }
    503 
    504 
    505 void wpas_notify_p2p_group_started(struct wpa_supplicant *wpa_s,
    506 				   struct wpa_ssid *ssid, int network_id,
    507 				   int client)
    508 {
    509 	/* Notify a group has been started */
    510 	wpas_dbus_register_p2p_group(wpa_s, ssid);
    511 
    512 	wpas_dbus_signal_p2p_group_started(wpa_s, ssid, client, network_id);
    513 }
    514 
    515 
    516 void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s,
    517 				struct wps_event_fail *fail)
    518 {
    519 	wpas_dbus_signal_p2p_wps_failed(wpa_s, fail);
    520 }
    521 
    522 #endif /* CONFIG_P2P */
    523 
    524 
    525 static void wpas_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
    526 					  const u8 *sta,
    527 					  const u8 *p2p_dev_addr)
    528 {
    529 #ifdef CONFIG_P2P
    530 	wpas_p2p_notify_ap_sta_authorized(wpa_s, p2p_dev_addr);
    531 
    532 	/*
    533 	 * Register a group member object corresponding to this peer and
    534 	 * emit a PeerJoined signal. This will check if it really is a
    535 	 * P2P group.
    536 	 */
    537 	wpas_dbus_register_p2p_groupmember(wpa_s, sta);
    538 
    539 	/*
    540 	 * Create 'peer-joined' signal on group object -- will also
    541 	 * check P2P itself.
    542 	 */
    543 	wpas_dbus_signal_p2p_peer_joined(wpa_s, sta);
    544 #endif /* CONFIG_P2P */
    545 }
    546 
    547 
    548 static void wpas_notify_ap_sta_deauthorized(struct wpa_supplicant *wpa_s,
    549 					    const u8 *sta)
    550 {
    551 #ifdef CONFIG_P2P
    552 	/*
    553 	 * Unregister a group member object corresponding to this peer
    554 	 * if this is a P2P group.
    555 	 */
    556 	wpas_dbus_unregister_p2p_groupmember(wpa_s, sta);
    557 
    558 	/*
    559 	 * Create 'peer-disconnected' signal on group object if this
    560 	 * is a P2P group.
    561 	 */
    562 	wpas_dbus_signal_p2p_peer_disconnected(wpa_s, sta);
    563 #endif /* CONFIG_P2P */
    564 }
    565 
    566 
    567 void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
    568 				const u8 *mac_addr, int authorized,
    569 				const u8 *p2p_dev_addr)
    570 {
    571 	if (authorized)
    572 		wpas_notify_ap_sta_authorized(wpa_s, mac_addr, p2p_dev_addr);
    573 	else
    574 		wpas_notify_ap_sta_deauthorized(wpa_s, mac_addr);
    575 }
    576 
    577 
    578 void wpas_notify_certification(struct wpa_supplicant *wpa_s, int depth,
    579 			       const char *subject, const char *cert_hash,
    580 			       const struct wpabuf *cert)
    581 {
    582 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT
    583 		"depth=%d subject='%s'%s%s",
    584 		depth, subject,
    585 		cert_hash ? " hash=" : "",
    586 		cert_hash ? cert_hash : "");
    587 
    588 	if (cert) {
    589 		char *cert_hex;
    590 		size_t len = wpabuf_len(cert) * 2 + 1;
    591 		cert_hex = os_malloc(len);
    592 		if (cert_hex) {
    593 			wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert),
    594 					 wpabuf_len(cert));
    595 			wpa_msg_ctrl(wpa_s, MSG_INFO,
    596 				     WPA_EVENT_EAP_PEER_CERT
    597 				     "depth=%d subject='%s' cert=%s",
    598 				     depth, subject, cert_hex);
    599 			os_free(cert_hex);
    600 		}
    601 	}
    602 
    603 	/* notify the old DBus API */
    604 	wpa_supplicant_dbus_notify_certification(wpa_s, depth, subject,
    605 						 cert_hash, cert);
    606 	/* notify the new DBus API */
    607 	wpas_dbus_signal_certification(wpa_s, depth, subject, cert_hash, cert);
    608 }
    609