From e50c50d5a090a6a52af6d92ee3a3c9cc37743747 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 13 Oct 2015 11:47:46 -0500 Subject: [PATCH] dbus: Expose interface globals via D-Bus properties All interface globals are now exposed as D-Bus properties of type string, and parsed via the normal interface global parsing functions. Signed-off-by: Dan Williams --- doc/dbus.doxygen | 245 ++++++++++++++++++++ wpa_supplicant/config.c | 17 ++ wpa_supplicant/config.h | 3 + wpa_supplicant/dbus/dbus_common_i.h | 10 +- wpa_supplicant/dbus/dbus_new.c | 269 +++++++++++++++++++--- wpa_supplicant/dbus/dbus_new_handlers.c | 73 ++++++ wpa_supplicant/dbus/dbus_new_handlers.h | 2 + wpa_supplicant/dbus/dbus_new_helpers.h | 2 + wpa_supplicant/dbus/dbus_new_introspect.c | 4 +- 9 files changed, 584 insertions(+), 41 deletions(-) diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen index 437f9fc0e..bd3e7f44c 100644 --- a/doc/dbus.doxygen +++ b/doc/dbus.doxygen @@ -678,6 +678,251 @@ fi.w1.wpa_supplicant1.CreateInterface.

DisconnectReason - i - (read)

The most recent IEEE 802.11 reason code for disconnect. Negative value indicates locally generated disconnection.

+ +
  • +

    EapolVersion - s - (read/write)

    +

    IEEE 802.1X/EAPOL version number

    +
  • + +
  • +

    Bgscan - s - (read/write)

    +

    Background scan and roaming parameters or an empty string if none

    +
  • + +
  • +

    DisableScanOffload - s - (read/write)

    +

    Disable automatic offloading of scan requests

    +
  • + +
  • +

    OpenscEnginePath - s - (read/write)

    +

    Path to the OpenSSL engine for opensc

    +
  • + +
  • +

    OpensslCiphers - s - (read/write)

    +

    OpenSSL cipher string

    +
  • + +
  • +

    PcscReader - s - (read/write)

    +

    PC/SC reader name prefix

    +
  • + +
  • +

    PcscPin - s - (read/write)

    +

    PIN for USIM, GSM SIM, and smartcards

    +
  • + +
  • +

    ExternalSim - s - (read/write)

    +

    Use external processing for SIM/USIM operations

    +
  • + +
  • +

    DriverParam - s - (read/write)

    +

    Driver interface parameters

    +
  • + +
  • +

    Dot11RSNAConfigPMKLifetime - s - (read/write)

    +

    Maximum lifetime of a PMK

    +
  • + +
  • +

    Dot11RSNAConfigPMKReauthThreshold - s - (read/write)

    +

    PMK re-authentication threshold

    +
  • + +
  • +

    Dot11RSNAConfigSATimeout - s - (read/write)

    +

    Security association timeout

    +
  • + +
  • +

    BssMaxCount - s - (read/write)

    +

    Maximum number of BSS entries to keep in memory

    +
  • + +
  • +

    FilterSsids - s - (read/write)

    +

    SSID-based scan result filtering

    +
  • + +
  • +

    FilterRssi - s - (read/write)

    +

    RSSI-based scan result filtering

    +
  • + +
  • +

    MaxNumSta - s - (read/write)

    +

    Maximum number of STAs in an AP/P2P GO

    +
  • + +
  • +

    DisassocLowAck - s - (read/write)

    +

    Disassocicate stations with massive packet loss

    +
  • + +
  • +

    Interworking - s - (read/write)

    +

    Whether Interworking (IEEE 802.11u) is enabled

    +
  • + +
  • +

    Hessid - s - (read/write)

    +

    Homogenous ESS identifier

    +
  • + +
  • +

    AccessNetworkType - s - (read/write)

    +

    Access Network Type

    +
  • + +
  • +

    PbcInM1 - s - (read/write)

    +

    AP mode WPS probing workaround for PBC with Windows 7

    +
  • + +
  • +

    Autoscan - s - (read/write)

    +

    Automatic scan parameters or an empty string if none

    +
  • + +
  • +

    WpsNfcDevPwId - s - (read/write)

    +

    NFC Device Password ID for password token

    +
  • + +
  • +

    WpsNfcDhPubkey - s - (read/write)

    +

    NFC DH Public Key for password token

    +
  • + +
  • +

    WpsNfcDhPrivkey - s - (read/write)

    +

    NFC DH Private Key for password token

    +
  • + +
  • +

    WpsNfcDevPw - s - (read/write)

    +

    NFC Device Password for password token

    +
  • + +
  • +

    ExtPasswordBackend - s - (read/write)

    +

    External password backend or an empty string if none

    +
  • + +
  • +

    P2pGoMaxInactivity - s - (read/write)

    +

    Timeout in seconds to detect STA inactivity

    +
  • + +
  • +

    AutoInterworking - s - (read/write)

    +

    Whether to use network selection automatically

    +
  • + +
  • +

    Okc - s - (read/write)

    +

    Whether to enable opportunistic key caching by default

    +
  • + +
  • +

    Pmf - s - (read/write)

    +

    Whether to enable/require PMF by default

    +
  • + +
  • +

    SaeGroups - s - (read/write)

    +

    Preference list of enabled groups for SAE

    +
  • + +
  • +

    DtimPeriod - s - (read/write)

    +

    Default DTIM period in Beacon intervals

    +
  • + +
  • +

    BeaconInt - s - (read/write)

    +

    Default Beacon interval in TU

    +
  • + +
  • +

    IgnoreOldScanRes - s - (read/write)

    +

    Ignore scan results older than request

    +
  • + +
  • +

    FreqList - s - (read/write)

    +

    Array of allowed scan frequencies or an empty string for all

    +
  • + +
  • +

    ScanCurFreq - s - (read/write)

    +

    Whether to scan only the current channel

    +
  • + +
  • +

    SchedScanInterval - s - (read/write)

    +

    schedule scan interval

    +
  • + +
  • +

    TdlsExternalControl - s - (read/write)

    +

    External control for TDLS setup requests

    +
  • + +
  • +

    OsuDir - s - (read/write)

    +

    OSU provider information directory

    +
  • + +
  • +

    WowlanTriggers - s - (read/write)

    +

    Wake-on-WLAN triggers

    +
  • + +
  • +

    P2pSearchDelay - s - (read/write)

    +

    Extra delay between concurrent search iterations

    +
  • + +
  • +

    MacAddr - s - (read/write)

    +

    MAC address policy default

    +
  • + +
  • +

    RandAddrLifetime - s - (read/write)

    +

    Lifetime of random MAC address in seconds

    +
  • + +
  • +

    PreassocMacAddr - s - (read/write)

    +

    Pre-association MAC address policy

    +
  • + +
  • +

    KeyMgmtOffload - s - (read/write)

    +

    Use key management offload

    +
  • + +
  • +

    PassiveScan - s - (read/write)

    +

    Whether to force passive scan for network connection

    +
  • + +
  • +

    ReassocSameBssOptim - s - (read/write)

    +

    Whether to optimize reassoc-to-same-BSS

    +
  • + +
  • +

    WpsPriority - s - (read/write)

    +

    Priority for the networks added through WPS

    +
  • \subsection dbus_interface_signals Signals diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index b1adab77b..03b91a22b 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -4304,6 +4304,23 @@ int wpa_config_get_value(const char *name, struct wpa_config *config, } +int wpa_config_get_num_global_field_names(void) +{ + return NUM_GLOBAL_FIELDS; +} + + +const char * wpa_config_get_global_field_name(unsigned int i, int *no_var) +{ + if (i >= NUM_GLOBAL_FIELDS) + return NULL; + + if (no_var) + *no_var = !global_fields[i].param1; + return global_fields[i].name; +} + + int wpa_config_process_global(struct wpa_config *config, char *pos, int line) { size_t i; diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 68d64fab0..3ee0797a6 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -1310,6 +1310,9 @@ void wpa_config_debug_dump_networks(struct wpa_config *config); /* Prototypes for common functions from config.c */ int wpa_config_process_global(struct wpa_config *config, char *pos, int line); +int wpa_config_get_num_global_field_names(void); + +const char * wpa_config_get_global_field_name(unsigned int i, int *no_var); /* Prototypes for backend specific functions from the selected config_*.c */ diff --git a/wpa_supplicant/dbus/dbus_common_i.h b/wpa_supplicant/dbus/dbus_common_i.h index a551ccd55..95eb4bcb5 100644 --- a/wpa_supplicant/dbus/dbus_common_i.h +++ b/wpa_supplicant/dbus/dbus_common_i.h @@ -13,6 +13,8 @@ #include +struct wpa_dbus_property_desc; + struct wpas_dbus_priv { DBusConnection *con; int should_dispatch; @@ -20,9 +22,13 @@ struct wpas_dbus_priv { u32 next_objid; int dbus_new_initialized; -#if defined(CONFIG_CTRL_IFACE_DBUS_NEW) && defined(CONFIG_AP) +#if defined(CONFIG_CTRL_IFACE_DBUS_NEW) + struct wpa_dbus_property_desc *all_interface_properties; + int globals_start; +#if defined(CONFIG_AP) int dbus_noc_refcnt; -#endif /* CONFIG_CTRL_IFACE_DBUS_NEW && CONFIG_AP */ +#endif /* CONFIG_AP */ +#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ }; #endif /* DBUS_COMMON_I_H */ diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 9b04ee1c7..16bada977 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -2184,35 +2184,42 @@ static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = { static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = { { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s", wpas_dbus_getter_debug_level, - wpas_dbus_setter_debug_level + wpas_dbus_setter_debug_level, + NULL }, { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b", wpas_dbus_getter_debug_timestamp, - wpas_dbus_setter_debug_timestamp + wpas_dbus_setter_debug_timestamp, + NULL }, { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b", wpas_dbus_getter_debug_show_keys, - wpas_dbus_setter_debug_show_keys + wpas_dbus_setter_debug_show_keys, + NULL }, { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao", wpas_dbus_getter_interfaces, + NULL, NULL }, { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as", wpas_dbus_getter_eap_methods, + NULL, NULL }, { "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as", wpas_dbus_getter_global_capabilities, + NULL, NULL }, #ifdef CONFIG_WIFI_DISPLAY { "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay", wpas_dbus_getter_global_wfd_ies, - wpas_dbus_setter_global_wfd_ies + wpas_dbus_setter_global_wfd_ies, + NULL }, #endif /* CONFIG_WIFI_DISPLAY */ - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = { @@ -2240,12 +2247,50 @@ static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = { }; +static char * uscore_to_dbus(const char *uscore) +{ + const char *p = uscore; + char *str, *s; + dbus_bool_t last_was_uscore = TRUE; + + s = str = os_zalloc(os_strlen(uscore) + 1); + if (!str) + return NULL; + while (p && *p) { + if (*p == '_') { + last_was_uscore = TRUE; + } else { + *s++ = last_was_uscore ? toupper(*p) : *p; + last_was_uscore = FALSE; + } + p++; + } + + return str; +} + + +static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv); + + +static void wpa_dbus_ctrl_iface_props_deinit(struct wpas_dbus_priv *priv) +{ + int idx = priv->globals_start; + + /* Free all allocated property values */ + while (priv->all_interface_properties[idx].dbus_property) + os_free((char *) + priv->all_interface_properties[idx++].dbus_property); + os_free((char *) priv->all_interface_properties); +} + + /** * wpas_dbus_ctrl_iface_init - Initialize dbus control interface * @global: Pointer to global data from wpa_supplicant_init() * Returns: 0 on success or -1 on failure * - * Initialize the dbus control interface for wpa_supplicantand and start + * Initialize the dbus control interface for wpa_supplicant and start * receiving commands from external programs over the bus. */ int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv) @@ -2253,11 +2298,18 @@ int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv) struct wpa_dbus_object_desc *obj_desc; int ret; + ret = wpa_dbus_ctrl_iface_props_init(priv); + if (ret < 0) { + wpa_printf(MSG_ERROR, + "dbus: Not enough memory to init interface properties"); + return -1; + } + obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc)); if (!obj_desc) { wpa_printf(MSG_ERROR, "Not enough memory to create object description"); - return -1; + goto error; } wpas_dbus_register(obj_desc, priv->global, NULL, @@ -2270,31 +2322,36 @@ int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv) ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH, WPAS_DBUS_NEW_SERVICE, obj_desc); - if (ret < 0) + if (ret < 0) { free_dbus_object_desc(obj_desc); - else - priv->dbus_new_initialized = 1; + goto error; + } - return ret; + priv->dbus_new_initialized = 1; + return 0; + +error: + wpa_dbus_ctrl_iface_props_deinit(priv); + return -1; } /** * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for * wpa_supplicant - * @iface: Pointer to dbus private data from wpas_dbus_init() + * @priv: Pointer to dbus private data from wpas_dbus_init() * * Deinitialize the dbus control interface that was initialized with * wpas_dbus_ctrl_iface_init(). */ -void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface) +void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *priv) { - if (!iface->dbus_new_initialized) + if (!priv->dbus_new_initialized) return; wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'", WPAS_DBUS_NEW_PATH); - dbus_connection_unregister_object_path(iface->con, - WPAS_DBUS_NEW_PATH); + dbus_connection_unregister_object_path(priv->con, WPAS_DBUS_NEW_PATH); + wpa_dbus_ctrl_iface_props_deinit(priv); } @@ -2307,13 +2364,15 @@ static void wpa_dbus_free(void *ptr) static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = { { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}", wpas_dbus_getter_network_properties, - wpas_dbus_setter_network_properties + wpas_dbus_setter_network_properties, + NULL }, { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b", wpas_dbus_getter_enabled, - wpas_dbus_setter_enabled + wpas_dbus_setter_enabled, + NULL }, - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; @@ -2452,53 +2511,65 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid) static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = { { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay", wpas_dbus_getter_bss_ssid, + NULL, NULL }, { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay", wpas_dbus_getter_bss_bssid, + NULL, NULL }, { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b", wpas_dbus_getter_bss_privacy, + NULL, NULL }, { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s", wpas_dbus_getter_bss_mode, + NULL, NULL }, { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n", wpas_dbus_getter_bss_signal, + NULL, NULL }, { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q", wpas_dbus_getter_bss_frequency, + NULL, NULL }, { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au", wpas_dbus_getter_bss_rates, + NULL, NULL }, { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", wpas_dbus_getter_bss_wpa, + NULL, NULL }, { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", wpas_dbus_getter_bss_rsn, + NULL, NULL }, { "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", wpas_dbus_getter_bss_wps, + NULL, NULL }, { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay", wpas_dbus_getter_bss_ies, + NULL, NULL }, { "Age", WPAS_DBUS_NEW_IFACE_BSS, "u", wpas_dbus_getter_bss_age, + NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; @@ -3004,125 +3075,154 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}", wpas_dbus_getter_capabilities, + NULL, NULL }, { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", wpas_dbus_getter_state, + NULL, NULL }, { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b", wpas_dbus_getter_scanning, + NULL, NULL }, { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", wpas_dbus_getter_ap_scan, - wpas_dbus_setter_ap_scan + wpas_dbus_setter_ap_scan, + NULL }, { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", wpas_dbus_getter_bss_expire_age, - wpas_dbus_setter_bss_expire_age + wpas_dbus_setter_bss_expire_age, + NULL }, { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", wpas_dbus_getter_bss_expire_count, - wpas_dbus_setter_bss_expire_count + wpas_dbus_setter_bss_expire_count, + NULL }, { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", wpas_dbus_getter_country, - wpas_dbus_setter_country + wpas_dbus_setter_country, + NULL }, { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", wpas_dbus_getter_ifname, + NULL, NULL }, { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", wpas_dbus_getter_driver, + NULL, NULL }, { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", wpas_dbus_getter_bridge_ifname, + NULL, NULL }, { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o", wpas_dbus_getter_current_bss, + NULL, NULL }, { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o", wpas_dbus_getter_current_network, + NULL, NULL }, { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", wpas_dbus_getter_current_auth_mode, + NULL, NULL }, { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}", wpas_dbus_getter_blobs, + NULL, NULL }, { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", wpas_dbus_getter_bsss, + NULL, NULL }, { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", wpas_dbus_getter_networks, + NULL, NULL }, { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b", wpas_dbus_getter_fast_reauth, - wpas_dbus_setter_fast_reauth + wpas_dbus_setter_fast_reauth, + NULL }, { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i", wpas_dbus_getter_scan_interval, - wpas_dbus_setter_scan_interval + wpas_dbus_setter_scan_interval, + NULL }, { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", wpas_dbus_getter_pkcs11_engine_path, + NULL, NULL }, { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", wpas_dbus_getter_pkcs11_module_path, + NULL, NULL }, #ifdef CONFIG_WPS { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b", wpas_dbus_getter_process_credentials, - wpas_dbus_setter_process_credentials + wpas_dbus_setter_process_credentials, + NULL }, { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s", wpas_dbus_getter_config_methods, - wpas_dbus_setter_config_methods + wpas_dbus_setter_config_methods, + NULL }, #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}", wpas_dbus_getter_p2p_device_config, - wpas_dbus_setter_p2p_device_config + wpas_dbus_setter_p2p_device_config, + NULL }, { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao", wpas_dbus_getter_p2p_peers, + NULL, NULL }, { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s", wpas_dbus_getter_p2p_role, + NULL, NULL }, { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o", wpas_dbus_getter_p2p_group, + NULL, NULL }, { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o", wpas_dbus_getter_p2p_peergo, + NULL, NULL }, { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao", wpas_dbus_getter_persistent_groups, + NULL, NULL }, #endif /* CONFIG_P2P */ { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i", wpas_dbus_getter_disconnect_reason, + NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { @@ -3396,6 +3496,77 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { }; +static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv) +{ + size_t all_size; + unsigned int i, j, count, num_const, num_globals; + const char *global_name; + static const char * const ignored_globals[] = { + "bss_expiration_age", "bss_expiration_scan_count", + "ap_scan", "country", "fast_reauth", + "pkcs11_engine_path", "pkcs11_module_path" + }; + + /* wpas_dbus_interface_properties terminates with a NULL element */ + num_const = ARRAY_SIZE(wpas_dbus_interface_properties) - 1; + + num_globals = wpa_config_get_num_global_field_names(); + priv->globals_start = num_const; + + /* allocate enough for all properties + terminating NULL element */ + all_size = (num_globals + num_const + 1) * + sizeof(wpas_dbus_interface_properties[0]); + priv->all_interface_properties = os_zalloc(all_size); + if (!priv->all_interface_properties) { + wpa_printf(MSG_ERROR, + "dbus: Not enough memory for interface properties"); + return -1; + } + + /* Copy constant interface properties to the start of the array */ + os_memcpy(priv->all_interface_properties, + wpas_dbus_interface_properties, + sizeof(wpas_dbus_interface_properties)); + + /* Dynamically construct interface global properties */ + for (i = 0, count = num_const; i < num_globals; i++) { + struct wpa_dbus_property_desc *desc; + int no_var = 0; + + /* ignore globals that are actually just methods */ + global_name = wpa_config_get_global_field_name(i, &no_var); + if (no_var) + continue; + /* Ignore fields already explicitly exposed */ + for (j = 0; j < ARRAY_SIZE(ignored_globals); j++) { + if (os_strcmp(global_name, ignored_globals[j]) == 0) + break; + } + if (j < ARRAY_SIZE(ignored_globals)) + continue; + + desc = &priv->all_interface_properties[count++]; + desc->dbus_property = uscore_to_dbus(global_name); + if (!desc->dbus_property) { + wpa_printf(MSG_ERROR, + "dbus: Not enough memory for D-Bus property name"); + goto error; + } + desc->dbus_interface = WPAS_DBUS_NEW_IFACE_INTERFACE; + desc->type = "s"; + desc->getter = wpas_dbus_getter_iface_global; + desc->setter = wpas_dbus_setter_iface_global; + desc->data = global_name; + } + + return 0; + +error: + wpa_dbus_ctrl_iface_props_deinit(priv); + return -1; +} + + /** * wpas_dbus_register_interface - Register an interface with D-Bus * @wpa_s: wpa_supplicant interface structure @@ -3403,7 +3574,6 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { */ int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s) { - struct wpa_dbus_object_desc *obj_desc = NULL; struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus; int next; @@ -3429,7 +3599,7 @@ int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s) } wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods, - wpas_dbus_interface_properties, + ctrl_iface->all_interface_properties, wpas_dbus_interface_signals); wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'", @@ -3495,65 +3665,80 @@ int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s) static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = { { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s", wpas_dbus_getter_p2p_peer_device_name, + NULL, NULL }, { "Manufacturer", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s", wpas_dbus_getter_p2p_peer_manufacturer, + NULL, NULL }, { "ModelName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s", wpas_dbus_getter_p2p_peer_modelname, + NULL, NULL }, { "ModelNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s", wpas_dbus_getter_p2p_peer_modelnumber, + NULL, NULL }, { "SerialNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s", wpas_dbus_getter_p2p_peer_serialnumber, + NULL, NULL }, { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay", wpas_dbus_getter_p2p_peer_primary_device_type, + NULL, NULL }, { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q", wpas_dbus_getter_p2p_peer_config_method, + NULL, NULL }, { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i", wpas_dbus_getter_p2p_peer_level, + NULL, NULL }, { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y", wpas_dbus_getter_p2p_peer_device_capability, + NULL, NULL }, { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y", wpas_dbus_getter_p2p_peer_group_capability, + NULL, NULL }, { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay", wpas_dbus_getter_p2p_peer_secondary_device_types, + NULL, NULL }, { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay", wpas_dbus_getter_p2p_peer_vendor_extension, + NULL, NULL }, { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay", wpas_dbus_getter_p2p_peer_ies, + NULL, NULL }, { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay", wpas_dbus_getter_p2p_peer_device_address, + NULL, NULL }, { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao", wpas_dbus_getter_p2p_peer_groups, + NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = { @@ -3811,41 +3996,50 @@ void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s, static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = { { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao", wpas_dbus_getter_p2p_group_members, + NULL, NULL }, { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o", wpas_dbus_getter_p2p_group, + NULL, NULL }, { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s", wpas_dbus_getter_p2p_role, + NULL, NULL }, { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay", wpas_dbus_getter_p2p_group_ssid, + NULL, NULL }, { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay", wpas_dbus_getter_p2p_group_bssid, + NULL, NULL }, { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q", wpas_dbus_getter_p2p_group_frequency, + NULL, NULL }, { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s", wpas_dbus_getter_p2p_group_passphrase, + NULL, NULL }, { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay", wpas_dbus_getter_p2p_group_psk, + NULL, NULL }, { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay", wpas_dbus_getter_p2p_group_vendor_ext, - wpas_dbus_setter_p2p_group_vendor_ext + wpas_dbus_setter_p2p_group_vendor_ext, + NULL }, - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = { @@ -3972,9 +4166,10 @@ static const struct wpa_dbus_property_desc wpas_dbus_persistent_group_properties[] = { { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}", wpas_dbus_getter_persistent_group_properties, - wpas_dbus_setter_persistent_group_properties + wpas_dbus_setter_persistent_group_properties, + NULL }, - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; /* No signals intended for persistent group objects */ diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index dbec764ec..a963e85c8 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -3441,6 +3441,79 @@ dbus_bool_t wpas_dbus_getter_blobs( } +dbus_bool_t wpas_dbus_getter_iface_global( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + int ret; + char buf[250]; + char *p = buf; + + if (!property_desc->data) { + dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, + "Unhandled interface property %s", + property_desc->dbus_property); + return FALSE; + } + + ret = wpa_config_get_value(property_desc->data, wpa_s->conf, buf, + sizeof(buf)); + if (ret < 0) + *p = '\0'; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &p, + error); +} + + +dbus_bool_t wpas_dbus_setter_iface_global( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + const char *new_value = NULL; + char buf[250]; + size_t combined_len; + int ret; + + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING, + &new_value)) + return FALSE; + + combined_len = os_strlen(property_desc->data) + os_strlen(new_value) + + 3; + if (combined_len >= sizeof(buf)) { + dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, + "Interface property %s value too large", + property_desc->dbus_property); + return FALSE; + } + + if (!new_value[0]) + new_value = "NULL"; + + ret = os_snprintf(buf, combined_len, "%s=%s", property_desc->data, + new_value); + if (os_snprintf_error(combined_len, ret)) { + dbus_set_error(error, WPAS_DBUS_ERROR_UNKNOWN_ERROR, + "Failed to construct new interface property %s", + property_desc->dbus_property); + return FALSE; + } + + if (wpa_config_process_global(wpa_s->conf, buf, -1)) { + dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, + "Failed to set interface property %s", + property_desc->dbus_property); + return FALSE; + } + + wpa_supplicant_update_config(wpa_s); + return TRUE; +} + + static struct wpa_bss * get_bss_helper(struct bss_handler_args *args, DBusError *error, const char *func_name) { diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index 0713ffcc1..1e9b1732a 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -64,6 +64,8 @@ DECLARE_ACCESSOR(wpas_dbus_setter_debug_show_keys); DECLARE_ACCESSOR(wpas_dbus_getter_interfaces); DECLARE_ACCESSOR(wpas_dbus_getter_eap_methods); DECLARE_ACCESSOR(wpas_dbus_getter_global_capabilities); +DECLARE_ACCESSOR(wpas_dbus_getter_iface_global); +DECLARE_ACCESSOR(wpas_dbus_setter_iface_global); DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, struct wpa_supplicant *wpa_s); diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h index 41ef79501..7b63b28d7 100644 --- a/wpa_supplicant/dbus/dbus_new_helpers.h +++ b/wpa_supplicant/dbus/dbus_new_helpers.h @@ -93,6 +93,8 @@ struct wpa_dbus_property_desc { WPADBusPropertyAccessor getter; /* property setter function */ WPADBusPropertyAccessor setter; + /* other data */ + const char *data; }; diff --git a/wpa_supplicant/dbus/dbus_new_introspect.c b/wpa_supplicant/dbus/dbus_new_introspect.c index fba57e636..aee105b4b 100644 --- a/wpa_supplicant/dbus/dbus_new_introspect.c +++ b/wpa_supplicant/dbus/dbus_new_introspect.c @@ -38,7 +38,7 @@ static struct interfaces * add_interface(struct dl_list *list, if (!iface) return NULL; iface->dbus_interface = os_strdup(dbus_interface); - iface->xml = wpabuf_alloc(6000); + iface->xml = wpabuf_alloc(15000); if (iface->dbus_interface == NULL || iface->xml == NULL) { os_free(iface->dbus_interface); wpabuf_free(iface->xml); @@ -257,7 +257,7 @@ DBusMessage * wpa_dbus_introspect(DBusMessage *message, DBusMessage *reply; struct wpabuf *xml; - xml = wpabuf_alloc(15000); + xml = wpabuf_alloc(20000); if (xml == NULL) return NULL;