$search
00001 /* 00002 * WPA Supplicant / dbus-based control interface 00003 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. 00004 * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com> 00005 * Copyright (c) 2009, Jouni Malinen <j@w1.fi> 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License version 2 as 00009 * published by the Free Software Foundation. 00010 * 00011 * Alternatively, this software may be distributed under the terms of BSD 00012 * license. 00013 * 00014 * See README and COPYING for more details. 00015 */ 00016 00017 #include "includes.h" 00018 00019 #include "common.h" 00020 #include "wps/wps.h" 00021 #include "../config.h" 00022 #include "../wpa_supplicant_i.h" 00023 #include "../bss.h" 00024 #include "dbus_new_helpers.h" 00025 #include "dbus_dict_helpers.h" 00026 #include "dbus_new.h" 00027 #include "dbus_new_handlers.h" 00028 #include "dbus_common.h" 00029 #include "dbus_common_i.h" 00030 00031 00040 static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s, 00041 const char *sig_name, int properties) 00042 { 00043 struct wpas_dbus_priv *iface; 00044 DBusMessage *msg; 00045 DBusMessageIter iter, iter_dict; 00046 00047 iface = wpa_s->global->dbus; 00048 00049 /* Do nothing if the control interface is not turned on */ 00050 if (iface == NULL) 00051 return; 00052 00053 msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH, 00054 WPAS_DBUS_NEW_INTERFACE, sig_name); 00055 if (msg == NULL) 00056 return; 00057 00058 dbus_message_iter_init_append(msg, &iter); 00059 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, 00060 &wpa_s->dbus_new_path)) 00061 goto err; 00062 00063 if (properties) { 00064 if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) 00065 goto err; 00066 00067 wpa_dbus_get_object_properties(iface, wpa_s->dbus_new_path, 00068 WPAS_DBUS_NEW_IFACE_INTERFACE, 00069 &iter_dict); 00070 00071 if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) 00072 goto err; 00073 } 00074 00075 dbus_connection_send(iface->con, msg, NULL); 00076 dbus_message_unref(msg); 00077 return; 00078 00079 err: 00080 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); 00081 dbus_message_unref(msg); 00082 } 00083 00084 00091 static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s) 00092 { 00093 wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE); 00094 } 00095 00096 00103 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s) 00104 { 00105 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE); 00106 00107 } 00108 00109 00117 void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success) 00118 { 00119 struct wpas_dbus_priv *iface; 00120 DBusMessage *msg; 00121 dbus_bool_t succ; 00122 00123 iface = wpa_s->global->dbus; 00124 00125 /* Do nothing if the control interface is not turned on */ 00126 if (iface == NULL) 00127 return; 00128 00129 msg = dbus_message_new_signal(wpa_s->dbus_new_path, 00130 WPAS_DBUS_NEW_IFACE_INTERFACE, 00131 "ScanDone"); 00132 if (msg == NULL) 00133 return; 00134 00135 succ = success ? TRUE : FALSE; 00136 if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ, 00137 DBUS_TYPE_INVALID)) 00138 dbus_connection_send(iface->con, msg, NULL); 00139 else 00140 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); 00141 dbus_message_unref(msg); 00142 } 00143 00144 00154 static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s, 00155 const char *bss_obj_path, 00156 const char *sig_name, int properties) 00157 { 00158 struct wpas_dbus_priv *iface; 00159 DBusMessage *msg; 00160 DBusMessageIter iter, iter_dict; 00161 00162 iface = wpa_s->global->dbus; 00163 00164 /* Do nothing if the control interface is not turned on */ 00165 if (iface == NULL) 00166 return; 00167 00168 msg = dbus_message_new_signal(wpa_s->dbus_new_path, 00169 WPAS_DBUS_NEW_IFACE_INTERFACE, 00170 sig_name); 00171 if (msg == NULL) 00172 return; 00173 00174 dbus_message_iter_init_append(msg, &iter); 00175 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, 00176 &bss_obj_path)) 00177 goto err; 00178 00179 if (properties) { 00180 if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) 00181 goto err; 00182 00183 wpa_dbus_get_object_properties(iface, bss_obj_path, 00184 WPAS_DBUS_NEW_IFACE_BSS, 00185 &iter_dict); 00186 00187 if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) 00188 goto err; 00189 } 00190 00191 dbus_connection_send(iface->con, msg, NULL); 00192 dbus_message_unref(msg); 00193 return; 00194 00195 err: 00196 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); 00197 dbus_message_unref(msg); 00198 } 00199 00200 00208 static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s, 00209 const char *bss_obj_path) 00210 { 00211 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE); 00212 } 00213 00214 00222 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s, 00223 const char *bss_obj_path) 00224 { 00225 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE); 00226 } 00227 00228 00237 static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s, 00238 const char *name, const char *sig_name) 00239 { 00240 struct wpas_dbus_priv *iface; 00241 DBusMessage *msg; 00242 00243 iface = wpa_s->global->dbus; 00244 00245 /* Do nothing if the control interface is not turned on */ 00246 if (iface == NULL) 00247 return; 00248 00249 msg = dbus_message_new_signal(wpa_s->dbus_new_path, 00250 WPAS_DBUS_NEW_IFACE_INTERFACE, 00251 sig_name); 00252 if (msg == NULL) 00253 return; 00254 00255 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, 00256 DBUS_TYPE_INVALID)) 00257 dbus_connection_send(iface->con, msg, NULL); 00258 else 00259 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); 00260 dbus_message_unref(msg); 00261 } 00262 00263 00271 void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s, 00272 const char *name) 00273 { 00274 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded"); 00275 } 00276 00277 00285 void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s, 00286 const char *name) 00287 { 00288 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved"); 00289 } 00290 00291 00301 static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s, 00302 int id, const char *sig_name, 00303 int properties) 00304 { 00305 struct wpas_dbus_priv *iface; 00306 DBusMessage *msg; 00307 DBusMessageIter iter, iter_dict; 00308 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; 00309 00310 iface = wpa_s->global->dbus; 00311 00312 /* Do nothing if the control interface is not turned on */ 00313 if (iface == NULL) 00314 return; 00315 00316 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, 00317 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", 00318 wpa_s->dbus_new_path, id); 00319 00320 msg = dbus_message_new_signal(wpa_s->dbus_new_path, 00321 WPAS_DBUS_NEW_IFACE_INTERFACE, 00322 sig_name); 00323 if (msg == NULL) 00324 return; 00325 00326 dbus_message_iter_init_append(msg, &iter); 00327 path = net_obj_path; 00328 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, 00329 &path)) 00330 goto err; 00331 00332 if (properties) { 00333 if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) 00334 goto err; 00335 00336 wpa_dbus_get_object_properties(iface, net_obj_path, 00337 WPAS_DBUS_NEW_IFACE_NETWORK, 00338 &iter_dict); 00339 00340 if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) 00341 goto err; 00342 } 00343 00344 dbus_connection_send(iface->con, msg, NULL); 00345 00346 dbus_message_unref(msg); 00347 return; 00348 00349 err: 00350 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); 00351 dbus_message_unref(msg); 00352 } 00353 00354 00362 static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s, 00363 int id) 00364 { 00365 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE); 00366 } 00367 00368 00376 static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s, 00377 int id) 00378 { 00379 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE); 00380 } 00381 00382 00390 void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id) 00391 { 00392 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE); 00393 } 00394 00395 00404 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s, 00405 struct wpa_ssid *ssid) 00406 { 00407 00408 char path[WPAS_DBUS_OBJECT_PATH_MAX]; 00409 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, 00410 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d", 00411 wpa_s->dbus_new_path, ssid->id); 00412 00413 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path, 00414 WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled"); 00415 } 00416 00417 00418 #ifdef CONFIG_WPS 00419 00426 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s) 00427 { 00428 00429 DBusMessage *msg; 00430 DBusMessageIter iter, dict_iter; 00431 struct wpas_dbus_priv *iface; 00432 char *key = "success"; 00433 00434 iface = wpa_s->global->dbus; 00435 00436 /* Do nothing if the control interface is not turned on */ 00437 if (iface == NULL) 00438 return; 00439 00440 msg = dbus_message_new_signal(wpa_s->dbus_new_path, 00441 WPAS_DBUS_NEW_IFACE_WPS, "Event"); 00442 if (msg == NULL) 00443 return; 00444 00445 dbus_message_iter_init_append(msg, &iter); 00446 00447 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) || 00448 !wpa_dbus_dict_open_write(&iter, &dict_iter) || 00449 !wpa_dbus_dict_close_write(&iter, &dict_iter)) 00450 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); 00451 else 00452 dbus_connection_send(iface->con, msg, NULL); 00453 00454 dbus_message_unref(msg); 00455 } 00456 00457 00465 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s, 00466 struct wps_event_fail *fail) 00467 { 00468 00469 DBusMessage *msg; 00470 DBusMessageIter iter, dict_iter; 00471 struct wpas_dbus_priv *iface; 00472 char *key = "fail"; 00473 00474 iface = wpa_s->global->dbus; 00475 00476 /* Do nothing if the control interface is not turned on */ 00477 if (iface == NULL) 00478 return; 00479 00480 msg = dbus_message_new_signal(wpa_s->dbus_new_path, 00481 WPAS_DBUS_NEW_IFACE_WPS, "Event"); 00482 if (msg == NULL) 00483 return; 00484 00485 dbus_message_iter_init_append(msg, &iter); 00486 00487 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) || 00488 !wpa_dbus_dict_open_write(&iter, &dict_iter) || 00489 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) || 00490 !wpa_dbus_dict_close_write(&iter, &dict_iter)) 00491 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); 00492 else 00493 dbus_connection_send(iface->con, msg, NULL); 00494 00495 dbus_message_unref(msg); 00496 } 00497 00498 00506 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s, 00507 struct wps_event_m2d *m2d) 00508 { 00509 00510 DBusMessage *msg; 00511 DBusMessageIter iter, dict_iter; 00512 struct wpas_dbus_priv *iface; 00513 char *key = "m2d"; 00514 00515 iface = wpa_s->global->dbus; 00516 00517 /* Do nothing if the control interface is not turned on */ 00518 if (iface == NULL) 00519 return; 00520 00521 msg = dbus_message_new_signal(wpa_s->dbus_new_path, 00522 WPAS_DBUS_NEW_IFACE_WPS, "Event"); 00523 if (msg == NULL) 00524 return; 00525 00526 dbus_message_iter_init_append(msg, &iter); 00527 00528 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) || 00529 !wpa_dbus_dict_open_write(&iter, &dict_iter) || 00530 !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods", 00531 m2d->config_methods) || 00532 !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer", 00533 (const char *) m2d->manufacturer, 00534 m2d->manufacturer_len) || 00535 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name", 00536 (const char *) m2d->model_name, 00537 m2d->model_name_len) || 00538 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number", 00539 (const char *) m2d->model_number, 00540 m2d->model_number_len) || 00541 !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number", 00542 (const char *) 00543 m2d->serial_number, 00544 m2d->serial_number_len) || 00545 !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name", 00546 (const char *) m2d->dev_name, 00547 m2d->dev_name_len) || 00548 !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type", 00549 (const char *) 00550 m2d->primary_dev_type, 8) || 00551 !wpa_dbus_dict_append_uint16(&dict_iter, "config_error", 00552 m2d->config_error) || 00553 !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id", 00554 m2d->dev_password_id) || 00555 !wpa_dbus_dict_close_write(&iter, &dict_iter)) 00556 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); 00557 else 00558 dbus_connection_send(iface->con, msg, NULL); 00559 00560 dbus_message_unref(msg); 00561 } 00562 00563 00570 void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s, 00571 const struct wps_credential *cred) 00572 { 00573 DBusMessage *msg; 00574 DBusMessageIter iter, dict_iter; 00575 struct wpas_dbus_priv *iface; 00576 char *auth_type[6]; /* we have six possible authorization types */ 00577 int at_num = 0; 00578 char *encr_type[4]; /* we have four possible encryption types */ 00579 int et_num = 0; 00580 00581 iface = wpa_s->global->dbus; 00582 00583 /* Do nothing if the control interface is not turned on */ 00584 if (iface == NULL) 00585 return; 00586 00587 msg = dbus_message_new_signal(wpa_s->dbus_new_path, 00588 WPAS_DBUS_NEW_IFACE_WPS, 00589 "Credentials"); 00590 if (msg == NULL) 00591 return; 00592 00593 dbus_message_iter_init_append(msg, &iter); 00594 if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) 00595 goto nomem; 00596 00597 if (cred->auth_type & WPS_AUTH_OPEN) 00598 auth_type[at_num++] = "open"; 00599 if (cred->auth_type & WPS_AUTH_WPAPSK) 00600 auth_type[at_num++] = "wpa-psk"; 00601 if (cred->auth_type & WPS_AUTH_SHARED) 00602 auth_type[at_num++] = "shared"; 00603 if (cred->auth_type & WPS_AUTH_WPA) 00604 auth_type[at_num++] = "wpa-eap"; 00605 if (cred->auth_type & WPS_AUTH_WPA2) 00606 auth_type[at_num++] = "wpa2-eap"; 00607 if (cred->auth_type & WPS_AUTH_WPA2PSK) 00608 auth_type[at_num++] = 00609 "wpa2-psk"; 00610 00611 if (cred->encr_type & WPS_ENCR_NONE) 00612 encr_type[et_num++] = "none"; 00613 if (cred->encr_type & WPS_ENCR_WEP) 00614 encr_type[et_num++] = "wep"; 00615 if (cred->encr_type & WPS_ENCR_TKIP) 00616 encr_type[et_num++] = "tkip"; 00617 if (cred->encr_type & WPS_ENCR_AES) 00618 encr_type[et_num++] = "aes"; 00619 00620 if (wpa_s->current_ssid) { 00621 if (!wpa_dbus_dict_append_byte_array( 00622 &dict_iter, "BSSID", 00623 (const char *) wpa_s->current_ssid->bssid, 00624 ETH_ALEN)) 00625 goto nomem; 00626 } 00627 00628 if (!wpa_dbus_dict_append_byte_array(&dict_iter, "SSID", 00629 (const char *) cred->ssid, 00630 cred->ssid_len) || 00631 !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType", 00632 (const char **) auth_type, 00633 at_num) || 00634 !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType", 00635 (const char **) encr_type, 00636 et_num) || 00637 !wpa_dbus_dict_append_byte_array(&dict_iter, "Key", 00638 (const char *) cred->key, 00639 cred->key_len) || 00640 !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex", 00641 cred->key_idx) || 00642 !wpa_dbus_dict_close_write(&iter, &dict_iter)) 00643 goto nomem; 00644 00645 dbus_connection_send(iface->con, msg, NULL); 00646 00647 nomem: 00648 dbus_message_unref(msg); 00649 } 00650 00651 #endif /* CONFIG_WPS */ 00652 00653 00662 void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s, 00663 enum wpas_dbus_prop property) 00664 { 00665 WPADBusPropertyAccessor getter; 00666 char *prop; 00667 00668 switch (property) { 00669 case WPAS_DBUS_PROP_AP_SCAN: 00670 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan; 00671 prop = "ApScan"; 00672 break; 00673 case WPAS_DBUS_PROP_SCANNING: 00674 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning; 00675 prop = "Scanning"; 00676 break; 00677 case WPAS_DBUS_PROP_STATE: 00678 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_state; 00679 prop = "State"; 00680 break; 00681 case WPAS_DBUS_PROP_CURRENT_BSS: 00682 getter = (WPADBusPropertyAccessor) 00683 wpas_dbus_getter_current_bss; 00684 prop = "CurrentBSS"; 00685 break; 00686 case WPAS_DBUS_PROP_CURRENT_NETWORK: 00687 getter = (WPADBusPropertyAccessor) 00688 wpas_dbus_getter_current_network; 00689 prop = "CurrentNetwork"; 00690 break; 00691 default: 00692 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d", 00693 __func__, property); 00694 return; 00695 } 00696 00697 wpa_dbus_mark_property_changed(wpa_s->global->dbus, 00698 wpa_s->dbus_new_path, 00699 WPAS_DBUS_NEW_IFACE_INTERFACE, prop); 00700 } 00701 00702 00712 void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s, 00713 enum wpas_dbus_bss_prop property, 00714 unsigned int id) 00715 { 00716 char path[WPAS_DBUS_OBJECT_PATH_MAX]; 00717 char *prop; 00718 00719 switch (property) { 00720 case WPAS_DBUS_BSS_PROP_SIGNAL: 00721 prop = "Signal"; 00722 break; 00723 case WPAS_DBUS_BSS_PROP_FREQ: 00724 prop = "Frequency"; 00725 break; 00726 case WPAS_DBUS_BSS_PROP_MODE: 00727 prop = "Mode"; 00728 break; 00729 case WPAS_DBUS_BSS_PROP_PRIVACY: 00730 prop = "Privacy"; 00731 break; 00732 case WPAS_DBUS_BSS_PROP_RATES: 00733 prop = "Rates"; 00734 break; 00735 case WPAS_DBUS_BSS_PROP_WPA: 00736 prop = "WPA"; 00737 break; 00738 case WPAS_DBUS_BSS_PROP_RSN: 00739 prop = "RSN"; 00740 break; 00741 case WPAS_DBUS_BSS_PROP_IES: 00742 prop = "IEs"; 00743 break; 00744 default: 00745 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d", 00746 __func__, property); 00747 return; 00748 } 00749 00750 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, 00751 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", 00752 wpa_s->dbus_new_path, id); 00753 00754 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path, 00755 WPAS_DBUS_NEW_IFACE_BSS, prop); 00756 } 00757 00758 00765 void wpas_dbus_signal_debug_level_changed(struct wpa_global *global) 00766 { 00767 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH, 00768 WPAS_DBUS_NEW_INTERFACE, 00769 "DebugLevel"); 00770 } 00771 00772 00779 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global) 00780 { 00781 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH, 00782 WPAS_DBUS_NEW_INTERFACE, 00783 "DebugTimestamp"); 00784 } 00785 00786 00793 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global) 00794 { 00795 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH, 00796 WPAS_DBUS_NEW_INTERFACE, 00797 "DebugShowKeys"); 00798 } 00799 00800 00801 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc, 00802 void *priv, 00803 WPADBusArgumentFreeFunction priv_free, 00804 const struct wpa_dbus_method_desc *methods, 00805 const struct wpa_dbus_property_desc *properties, 00806 const struct wpa_dbus_signal_desc *signals) 00807 { 00808 int n; 00809 00810 obj_desc->user_data = priv; 00811 obj_desc->user_data_free_func = priv_free; 00812 obj_desc->methods = methods; 00813 obj_desc->properties = properties; 00814 obj_desc->signals = signals; 00815 00816 for (n = 0; properties && properties->dbus_property; properties++) 00817 n++; 00818 00819 obj_desc->prop_changed_flags = os_zalloc(n); 00820 if (!obj_desc->prop_changed_flags) 00821 wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers", 00822 __func__); 00823 } 00824 00825 00826 static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = { 00827 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE, 00828 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface, 00829 { 00830 { "args", "a{sv}", ARG_IN }, 00831 { "path", "o", ARG_OUT }, 00832 END_ARGS 00833 } 00834 }, 00835 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE, 00836 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface, 00837 { 00838 { "path", "o", ARG_IN }, 00839 END_ARGS 00840 } 00841 }, 00842 { "GetInterface", WPAS_DBUS_NEW_INTERFACE, 00843 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface, 00844 { 00845 { "ifname", "s", ARG_IN }, 00846 { "path", "o", ARG_OUT }, 00847 END_ARGS 00848 } 00849 }, 00850 { NULL, NULL, NULL, { END_ARGS } } 00851 }; 00852 00853 static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = { 00854 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s", 00855 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level, 00856 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level, 00857 RW 00858 }, 00859 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b", 00860 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp, 00861 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp, 00862 RW 00863 }, 00864 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b", 00865 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys, 00866 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys, 00867 RW 00868 }, 00869 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao", 00870 (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces, 00871 NULL, 00872 R 00873 }, 00874 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as", 00875 (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods, 00876 NULL, 00877 R 00878 }, 00879 { NULL, NULL, NULL, NULL, NULL, 0 } 00880 }; 00881 00882 static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = { 00883 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE, 00884 { 00885 { "path", "o", ARG_OUT }, 00886 { "properties", "a{sv}", ARG_OUT }, 00887 END_ARGS 00888 } 00889 }, 00890 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE, 00891 { 00892 { "path", "o", ARG_OUT }, 00893 END_ARGS 00894 } 00895 }, 00896 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE, 00897 { 00898 { "properties", "a{sv}", ARG_OUT }, 00899 END_ARGS 00900 } 00901 }, 00902 { NULL, NULL, { END_ARGS } } 00903 }; 00904 00905 00914 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv) 00915 { 00916 struct wpa_dbus_object_desc *obj_desc; 00917 int ret; 00918 00919 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc)); 00920 if (!obj_desc) { 00921 wpa_printf(MSG_ERROR, "Not enough memory " 00922 "to create object description"); 00923 return -1; 00924 } 00925 00926 wpas_dbus_register(obj_desc, priv->global, NULL, 00927 wpas_dbus_global_methods, 00928 wpas_dbus_global_properties, 00929 wpas_dbus_global_signals); 00930 00931 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'", 00932 WPAS_DBUS_NEW_PATH); 00933 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH, 00934 WPAS_DBUS_NEW_SERVICE, 00935 obj_desc); 00936 if (ret < 0) 00937 free_dbus_object_desc(obj_desc); 00938 else 00939 priv->dbus_new_initialized = 1; 00940 00941 return ret; 00942 } 00943 00944 00953 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface) 00954 { 00955 if (!iface->dbus_new_initialized) 00956 return; 00957 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'", 00958 WPAS_DBUS_NEW_PATH); 00959 dbus_connection_unregister_object_path(iface->con, 00960 WPAS_DBUS_NEW_PATH); 00961 } 00962 00963 00964 static void wpa_dbus_free(void *ptr) 00965 { 00966 os_free(ptr); 00967 } 00968 00969 00970 static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = { 00971 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}", 00972 (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties, 00973 (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties, 00974 RW 00975 }, 00976 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b", 00977 (WPADBusPropertyAccessor) wpas_dbus_getter_enabled, 00978 (WPADBusPropertyAccessor) wpas_dbus_setter_enabled, 00979 RW 00980 }, 00981 { NULL, NULL, NULL, NULL, NULL, 0 } 00982 }; 00983 00984 00985 static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = { 00986 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK, 00987 { 00988 { "properties", "a{sv}", ARG_OUT }, 00989 END_ARGS 00990 } 00991 }, 00992 { NULL, NULL, { END_ARGS } } 00993 }; 00994 00995 01004 int wpas_dbus_register_network(struct wpa_supplicant *wpa_s, 01005 struct wpa_ssid *ssid) 01006 { 01007 struct wpas_dbus_priv *ctrl_iface; 01008 struct wpa_dbus_object_desc *obj_desc; 01009 struct network_handler_args *arg; 01010 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; 01011 01012 /* Do nothing if the control interface is not turned on */ 01013 if (wpa_s == NULL || wpa_s->global == NULL) 01014 return 0; 01015 ctrl_iface = wpa_s->global->dbus; 01016 if (ctrl_iface == NULL) 01017 return 0; 01018 01019 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, 01020 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", 01021 wpa_s->dbus_new_path, ssid->id); 01022 01023 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'", 01024 net_obj_path); 01025 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc)); 01026 if (!obj_desc) { 01027 wpa_printf(MSG_ERROR, "Not enough memory " 01028 "to create object description"); 01029 goto err; 01030 } 01031 01032 /* allocate memory for handlers arguments */ 01033 arg = os_zalloc(sizeof(struct network_handler_args)); 01034 if (!arg) { 01035 wpa_printf(MSG_ERROR, "Not enough memory " 01036 "to create arguments for method"); 01037 goto err; 01038 } 01039 01040 arg->wpa_s = wpa_s; 01041 arg->ssid = ssid; 01042 01043 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL, 01044 wpas_dbus_network_properties, 01045 wpas_dbus_network_signals); 01046 01047 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path, 01048 wpa_s->ifname, obj_desc)) 01049 goto err; 01050 01051 wpas_dbus_signal_network_added(wpa_s, ssid->id); 01052 01053 return 0; 01054 01055 err: 01056 free_dbus_object_desc(obj_desc); 01057 return -1; 01058 } 01059 01060 01069 int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid) 01070 { 01071 struct wpas_dbus_priv *ctrl_iface; 01072 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; 01073 int ret; 01074 01075 /* Do nothing if the control interface is not turned on */ 01076 if (wpa_s == NULL || wpa_s->global == NULL || 01077 wpa_s->dbus_new_path == NULL) 01078 return 0; 01079 ctrl_iface = wpa_s->global->dbus; 01080 if (ctrl_iface == NULL) 01081 return 0; 01082 01083 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, 01084 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", 01085 wpa_s->dbus_new_path, nid); 01086 01087 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'", 01088 net_obj_path); 01089 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path); 01090 01091 if (!ret) 01092 wpas_dbus_signal_network_removed(wpa_s, nid); 01093 01094 return ret; 01095 } 01096 01097 01098 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = { 01099 { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay", 01100 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid, 01101 NULL, 01102 R 01103 }, 01104 { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay", 01105 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid, 01106 NULL, 01107 R 01108 }, 01109 { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b", 01110 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy, 01111 NULL, 01112 R 01113 }, 01114 { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s", 01115 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode, 01116 NULL, 01117 R 01118 }, 01119 { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n", 01120 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal, 01121 NULL, 01122 R 01123 }, 01124 { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q", 01125 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency, 01126 NULL, 01127 R 01128 }, 01129 { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au", 01130 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rates, 01131 NULL, 01132 R 01133 }, 01134 { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", 01135 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpa, 01136 NULL, 01137 R 01138 }, 01139 { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", 01140 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsn, 01141 NULL, 01142 R 01143 }, 01144 { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay", 01145 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ies, 01146 NULL, 01147 R 01148 }, 01149 { NULL, NULL, NULL, NULL, NULL, 0 } 01150 }; 01151 01152 01153 static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = { 01154 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS, 01155 { 01156 { "properties", "a{sv}", ARG_OUT }, 01157 END_ARGS 01158 } 01159 }, 01160 { NULL, NULL, { END_ARGS } } 01161 }; 01162 01163 01173 int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s, 01174 u8 bssid[ETH_ALEN], unsigned int id) 01175 { 01176 struct wpas_dbus_priv *ctrl_iface; 01177 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; 01178 01179 /* Do nothing if the control interface is not turned on */ 01180 if (wpa_s == NULL || wpa_s->global == NULL) 01181 return 0; 01182 ctrl_iface = wpa_s->global->dbus; 01183 if (ctrl_iface == NULL) 01184 return 0; 01185 01186 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, 01187 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", 01188 wpa_s->dbus_new_path, id); 01189 01190 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'", 01191 bss_obj_path); 01192 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) { 01193 wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s", 01194 bss_obj_path); 01195 return -1; 01196 } 01197 01198 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path); 01199 01200 return 0; 01201 } 01202 01203 01213 int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, 01214 u8 bssid[ETH_ALEN], unsigned int id) 01215 { 01216 struct wpas_dbus_priv *ctrl_iface; 01217 struct wpa_dbus_object_desc *obj_desc; 01218 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; 01219 struct bss_handler_args *arg; 01220 01221 /* Do nothing if the control interface is not turned on */ 01222 if (wpa_s == NULL || wpa_s->global == NULL) 01223 return 0; 01224 ctrl_iface = wpa_s->global->dbus; 01225 if (ctrl_iface == NULL) 01226 return 0; 01227 01228 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, 01229 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", 01230 wpa_s->dbus_new_path, id); 01231 01232 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc)); 01233 if (!obj_desc) { 01234 wpa_printf(MSG_ERROR, "Not enough memory " 01235 "to create object description"); 01236 goto err; 01237 } 01238 01239 arg = os_zalloc(sizeof(struct bss_handler_args)); 01240 if (!arg) { 01241 wpa_printf(MSG_ERROR, "Not enough memory " 01242 "to create arguments for handler"); 01243 goto err; 01244 } 01245 arg->wpa_s = wpa_s; 01246 arg->id = id; 01247 01248 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL, 01249 wpas_dbus_bss_properties, 01250 wpas_dbus_bss_signals); 01251 01252 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'", 01253 bss_obj_path); 01254 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path, 01255 wpa_s->ifname, obj_desc)) { 01256 wpa_printf(MSG_ERROR, 01257 "Cannot register BSSID dbus object %s.", 01258 bss_obj_path); 01259 goto err; 01260 } 01261 01262 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path); 01263 01264 return 0; 01265 01266 err: 01267 free_dbus_object_desc(obj_desc); 01268 return -1; 01269 } 01270 01271 01272 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { 01273 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE, 01274 (WPADBusMethodHandler) &wpas_dbus_handler_scan, 01275 { 01276 { "args", "a{sv}", ARG_IN }, 01277 END_ARGS 01278 } 01279 }, 01280 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE, 01281 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect, 01282 { 01283 END_ARGS 01284 } 01285 }, 01286 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, 01287 (WPADBusMethodHandler) &wpas_dbus_handler_add_network, 01288 { 01289 { "args", "a{sv}", ARG_IN }, 01290 { "path", "o", ARG_OUT }, 01291 END_ARGS 01292 } 01293 }, 01294 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, 01295 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network, 01296 { 01297 { "path", "o", ARG_IN }, 01298 END_ARGS 01299 } 01300 }, 01301 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, 01302 (WPADBusMethodHandler) &wpas_dbus_handler_select_network, 01303 { 01304 { "path", "o", ARG_IN }, 01305 END_ARGS 01306 } 01307 }, 01308 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE, 01309 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob, 01310 { 01311 { "name", "s", ARG_IN }, 01312 { "data", "ay", ARG_IN }, 01313 END_ARGS 01314 } 01315 }, 01316 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE, 01317 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob, 01318 { 01319 { "name", "s", ARG_IN }, 01320 { "data", "ay", ARG_OUT }, 01321 END_ARGS 01322 } 01323 }, 01324 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE, 01325 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob, 01326 { 01327 { "name", "s", ARG_IN }, 01328 END_ARGS 01329 } 01330 }, 01331 #ifdef CONFIG_WPS 01332 { "Start", WPAS_DBUS_NEW_IFACE_WPS, 01333 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start, 01334 { 01335 { "args", "a{sv}", ARG_IN }, 01336 { "output", "a{sv}", ARG_OUT }, 01337 END_ARGS 01338 } 01339 }, 01340 #endif /* CONFIG_WPS */ 01341 { NULL, NULL, NULL, { END_ARGS } } 01342 }; 01343 01344 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { 01345 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}", 01346 (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities, 01347 NULL, R 01348 }, 01349 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", 01350 (WPADBusPropertyAccessor) wpas_dbus_getter_state, 01351 NULL, R 01352 }, 01353 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b", 01354 (WPADBusPropertyAccessor) wpas_dbus_getter_scanning, 01355 NULL, R 01356 }, 01357 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", 01358 (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan, 01359 (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan, 01360 RW 01361 }, 01362 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", 01363 (WPADBusPropertyAccessor) wpas_dbus_getter_ifname, 01364 NULL, R 01365 }, 01366 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", 01367 (WPADBusPropertyAccessor) wpas_dbus_getter_driver, 01368 NULL, R 01369 }, 01370 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", 01371 (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname, 01372 NULL, R 01373 }, 01374 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o", 01375 (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss, 01376 NULL, R 01377 }, 01378 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o", 01379 (WPADBusPropertyAccessor) wpas_dbus_getter_current_network, 01380 NULL, R 01381 }, 01382 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}", 01383 (WPADBusPropertyAccessor) wpas_dbus_getter_blobs, 01384 NULL, R 01385 }, 01386 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", 01387 (WPADBusPropertyAccessor) wpas_dbus_getter_bsss, 01388 NULL, R 01389 }, 01390 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", 01391 (WPADBusPropertyAccessor) wpas_dbus_getter_networks, 01392 NULL, R 01393 }, 01394 #ifdef CONFIG_WPS 01395 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b", 01396 (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials, 01397 (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials, 01398 RW 01399 }, 01400 #endif /* CONFIG_WPS */ 01401 { NULL, NULL, NULL, NULL, NULL, 0 } 01402 }; 01403 01404 static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { 01405 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE, 01406 { 01407 { "success", "b", ARG_OUT }, 01408 END_ARGS 01409 } 01410 }, 01411 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE, 01412 { 01413 { "path", "o", ARG_OUT }, 01414 { "properties", "a{sv}", ARG_OUT }, 01415 END_ARGS 01416 } 01417 }, 01418 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE, 01419 { 01420 { "path", "o", ARG_OUT }, 01421 END_ARGS 01422 } 01423 }, 01424 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE, 01425 { 01426 { "name", "s", ARG_OUT }, 01427 END_ARGS 01428 } 01429 }, 01430 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE, 01431 { 01432 { "name", "s", ARG_OUT }, 01433 END_ARGS 01434 } 01435 }, 01436 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE, 01437 { 01438 { "path", "o", ARG_OUT }, 01439 { "properties", "a{sv}", ARG_OUT }, 01440 END_ARGS 01441 } 01442 }, 01443 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE, 01444 { 01445 { "path", "o", ARG_OUT }, 01446 END_ARGS 01447 } 01448 }, 01449 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE, 01450 { 01451 { "path", "o", ARG_OUT }, 01452 END_ARGS 01453 } 01454 }, 01455 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE, 01456 { 01457 { "properties", "a{sv}", ARG_OUT }, 01458 END_ARGS 01459 } 01460 }, 01461 #ifdef CONFIG_WPS 01462 { "Event", WPAS_DBUS_NEW_IFACE_WPS, 01463 { 01464 { "name", "s", ARG_OUT }, 01465 { "args", "a{sv}", ARG_OUT }, 01466 END_ARGS 01467 } 01468 }, 01469 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS, 01470 { 01471 { "credentials", "a{sv}", ARG_OUT }, 01472 END_ARGS 01473 } 01474 }, 01475 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS, 01476 { 01477 { "properties", "a{sv}", ARG_OUT }, 01478 END_ARGS 01479 } 01480 }, 01481 #endif /* CONFIG_WPS */ 01482 { NULL, NULL, { END_ARGS } } 01483 }; 01484 01485 01486 int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s) 01487 { 01488 01489 struct wpa_dbus_object_desc *obj_desc = NULL; 01490 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus; 01491 int next; 01492 01493 /* Do nothing if the control interface is not turned on */ 01494 if (ctrl_iface == NULL) 01495 return 0; 01496 01497 /* Create and set the interface's object path */ 01498 wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); 01499 if (wpa_s->dbus_new_path == NULL) 01500 return -1; 01501 next = ctrl_iface->next_objid++; 01502 os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX, 01503 WPAS_DBUS_NEW_PATH_INTERFACES "/%u", 01504 next); 01505 01506 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc)); 01507 if (!obj_desc) { 01508 wpa_printf(MSG_ERROR, "Not enough memory " 01509 "to create object description"); 01510 goto err; 01511 } 01512 01513 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods, 01514 wpas_dbus_interface_properties, 01515 wpas_dbus_interface_signals); 01516 01517 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'", 01518 wpa_s->dbus_new_path); 01519 if (wpa_dbus_register_object_per_iface(ctrl_iface, 01520 wpa_s->dbus_new_path, 01521 wpa_s->ifname, obj_desc)) 01522 goto err; 01523 01524 wpas_dbus_signal_interface_added(wpa_s); 01525 01526 return 0; 01527 01528 err: 01529 os_free(wpa_s->dbus_new_path); 01530 wpa_s->dbus_new_path = NULL; 01531 free_dbus_object_desc(obj_desc); 01532 return -1; 01533 } 01534 01535 01536 int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s) 01537 { 01538 struct wpas_dbus_priv *ctrl_iface; 01539 01540 /* Do nothing if the control interface is not turned on */ 01541 if (wpa_s == NULL || wpa_s->global == NULL) 01542 return 0; 01543 ctrl_iface = wpa_s->global->dbus; 01544 if (ctrl_iface == NULL) 01545 return 0; 01546 01547 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'", 01548 wpa_s->dbus_new_path); 01549 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, 01550 wpa_s->dbus_new_path)) 01551 return -1; 01552 01553 wpas_dbus_signal_interface_removed(wpa_s); 01554 01555 os_free(wpa_s->dbus_new_path); 01556 wpa_s->dbus_new_path = NULL; 01557 01558 return 0; 01559 }