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