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