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