dbus: Expose interface globals via D-Bus properties
authorDan Williams <dcbw@redhat.com>
Tue, 13 Oct 2015 16:47:46 +0000 (11:47 -0500)
committerJouni Malinen <j@w1.fi>
Wed, 28 Oct 2015 21:41:32 +0000 (23:41 +0200)
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 <dcbw@redhat.com>
doc/dbus.doxygen
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/dbus/dbus_common_i.h
wpa_supplicant/dbus/dbus_new.c
wpa_supplicant/dbus/dbus_new_handlers.c
wpa_supplicant/dbus/dbus_new_handlers.h
wpa_supplicant/dbus/dbus_new_helpers.h
wpa_supplicant/dbus/dbus_new_introspect.c

index 437f9fc..bd3e7f4 100644 (file)
@@ -678,6 +678,251 @@ fi.w1.wpa_supplicant1.CreateInterface.
        <h3>DisconnectReason - i - (read)</h3>
        <p>The most recent IEEE 802.11 reason code for disconnect. Negative value indicates locally generated disconnection.</p>
       </li>
+
+      <li>
+       <h3>EapolVersion - s - (read/write)</h3>
+       <p>IEEE 802.1X/EAPOL version number</p>
+      </li>
+
+      <li>
+       <h3>Bgscan - s - (read/write)</h3>
+       <p>Background scan and roaming parameters or an empty string if none</p>
+      </li>
+
+      <li>
+       <h3>DisableScanOffload - s - (read/write)</h3>
+       <p>Disable automatic offloading of scan requests</p>
+      </li>
+
+      <li>
+       <h3>OpenscEnginePath - s - (read/write)</h3>
+       <p>Path to the OpenSSL engine for opensc</p>
+      </li>
+
+      <li>
+       <h3>OpensslCiphers - s - (read/write)</h3>
+       <p>OpenSSL cipher string</p>
+      </li>
+
+      <li>
+       <h3>PcscReader - s - (read/write)</h3>
+       <p>PC/SC reader name prefix</p>
+      </li>
+
+      <li>
+       <h3>PcscPin - s - (read/write)</h3>
+       <p>PIN for USIM, GSM SIM, and smartcards</p>
+      </li>
+
+      <li>
+       <h3>ExternalSim - s - (read/write)</h3>
+       <p>Use external processing for SIM/USIM operations</p>
+      </li>
+
+      <li>
+       <h3>DriverParam - s - (read/write)</h3>
+       <p>Driver interface parameters</p>
+      </li>
+
+      <li>
+       <h3>Dot11RSNAConfigPMKLifetime - s - (read/write)</h3>
+       <p>Maximum lifetime of a PMK</p>
+      </li>
+
+      <li>
+       <h3>Dot11RSNAConfigPMKReauthThreshold - s - (read/write)</h3>
+       <p>PMK re-authentication threshold</p>
+      </li>
+
+      <li>
+       <h3>Dot11RSNAConfigSATimeout - s - (read/write)</h3>
+       <p>Security association timeout</p>
+      </li>
+
+      <li>
+       <h3>BssMaxCount - s - (read/write)</h3>
+       <p>Maximum number of BSS entries to keep in memory</p>
+      </li>
+
+      <li>
+       <h3>FilterSsids - s - (read/write)</h3>
+       <p>SSID-based scan result filtering</p>
+      </li>
+
+      <li>
+       <h3>FilterRssi - s - (read/write)</h3>
+       <p>RSSI-based scan result filtering</p>
+      </li>
+
+      <li>
+       <h3>MaxNumSta - s - (read/write)</h3>
+       <p>Maximum number of STAs in an AP/P2P GO</p>
+      </li>
+
+      <li>
+       <h3>DisassocLowAck - s - (read/write)</h3>
+       <p>Disassocicate stations with massive packet loss</p>
+      </li>
+
+      <li>
+       <h3>Interworking - s - (read/write)</h3>
+       <p>Whether Interworking (IEEE 802.11u) is enabled</p>
+      </li>
+
+      <li>
+       <h3>Hessid - s - (read/write)</h3>
+       <p>Homogenous ESS identifier</p>
+      </li>
+
+      <li>
+       <h3>AccessNetworkType - s - (read/write)</h3>
+       <p>Access Network Type</p>
+      </li>
+
+      <li>
+       <h3>PbcInM1 - s - (read/write)</h3>
+       <p>AP mode WPS probing workaround for PBC with Windows 7</p>
+      </li>
+
+      <li>
+       <h3>Autoscan - s - (read/write)</h3>
+       <p>Automatic scan parameters or an empty string if none</p>
+      </li>
+
+      <li>
+       <h3>WpsNfcDevPwId - s - (read/write)</h3>
+       <p>NFC Device Password ID for password token</p>
+      </li>
+
+      <li>
+       <h3>WpsNfcDhPubkey - s - (read/write)</h3>
+       <p>NFC DH Public Key for password token</p>
+      </li>
+
+      <li>
+       <h3>WpsNfcDhPrivkey - s - (read/write)</h3>
+       <p>NFC DH Private Key for password token</p>
+      </li>
+
+      <li>
+       <h3>WpsNfcDevPw - s - (read/write)</h3>
+       <p>NFC Device Password for password token</p>
+      </li>
+
+      <li>
+       <h3>ExtPasswordBackend - s - (read/write)</h3>
+       <p>External password backend or an empty string if none</p>
+      </li>
+
+      <li>
+       <h3>P2pGoMaxInactivity - s - (read/write)</h3>
+       <p>Timeout in seconds to detect STA inactivity</p>
+      </li>
+
+      <li>
+       <h3>AutoInterworking - s - (read/write)</h3>
+       <p>Whether to use network selection automatically</p>
+      </li>
+
+      <li>
+       <h3>Okc - s - (read/write)</h3>
+       <p>Whether to enable opportunistic key caching by default</p>
+      </li>
+
+      <li>
+       <h3>Pmf - s - (read/write)</h3>
+       <p>Whether to enable/require PMF by default</p>
+      </li>
+
+      <li>
+       <h3>SaeGroups - s - (read/write)</h3>
+       <p>Preference list of enabled groups for SAE</p>
+      </li>
+
+      <li>
+       <h3>DtimPeriod - s - (read/write)</h3>
+       <p>Default DTIM period in Beacon intervals</p>
+      </li>
+
+      <li>
+       <h3>BeaconInt - s - (read/write)</h3>
+       <p>Default Beacon interval in TU</p>
+      </li>
+
+      <li>
+       <h3>IgnoreOldScanRes - s - (read/write)</h3>
+       <p>Ignore scan results older than request</p>
+      </li>
+
+      <li>
+       <h3>FreqList - s - (read/write)</h3>
+       <p>Array of allowed scan frequencies or an empty string for all</p>
+      </li>
+
+      <li>
+       <h3>ScanCurFreq - s - (read/write)</h3>
+       <p>Whether to scan only the current channel</p>
+      </li>
+
+      <li>
+       <h3>SchedScanInterval - s - (read/write)</h3>
+       <p>schedule scan interval</p>
+      </li>
+
+      <li>
+       <h3>TdlsExternalControl - s - (read/write)</h3>
+       <p>External control for TDLS setup requests</p>
+      </li>
+
+      <li>
+       <h3>OsuDir - s - (read/write)</h3>
+       <p>OSU provider information directory</p>
+      </li>
+
+      <li>
+       <h3>WowlanTriggers - s - (read/write)</h3>
+       <p>Wake-on-WLAN triggers</p>
+      </li>
+
+      <li>
+       <h3>P2pSearchDelay - s - (read/write)</h3>
+       <p>Extra delay between concurrent search iterations</p>
+      </li>
+
+      <li>
+       <h3>MacAddr - s - (read/write)</h3>
+       <p>MAC address policy default</p>
+      </li>
+
+      <li>
+       <h3>RandAddrLifetime - s - (read/write)</h3>
+       <p>Lifetime of random MAC address in seconds</p>
+      </li>
+
+      <li>
+       <h3>PreassocMacAddr - s - (read/write)</h3>
+       <p>Pre-association MAC address policy</p>
+      </li>
+
+      <li>
+       <h3>KeyMgmtOffload - s - (read/write)</h3>
+       <p>Use key management offload</p>
+      </li>
+
+      <li>
+       <h3>PassiveScan - s - (read/write)</h3>
+       <p>Whether to force passive scan for network connection</p>
+      </li>
+
+      <li>
+       <h3>ReassocSameBssOptim - s - (read/write)</h3>
+       <p>Whether to optimize reassoc-to-same-BSS</p>
+      </li>
+
+      <li>
+       <h3>WpsPriority - s - (read/write)</h3>
+       <p>Priority for the networks added through WPS</p>
+      </li>
     </ul>
 
 \subsection dbus_interface_signals Signals
index b1adab7..03b91a2 100644 (file)
@@ -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;
index 68d64fa..3ee0797 100644 (file)
@@ -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 */
 
index a551ccd..95eb4bc 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <dbus/dbus.h>
 
+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 */
index 9b04ee1..16bada9 100644 (file)
@@ -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 */
index dbec764..a963e85 100644 (file)
@@ -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)
 {
index 0713ffc..1e9b173 100644 (file)
@@ -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);
index 41ef795..7b63b28 100644 (file)
@@ -93,6 +93,8 @@ struct wpa_dbus_property_desc {
        WPADBusPropertyAccessor getter;
        /* property setter function */
        WPADBusPropertyAccessor setter;
+       /* other data */
+       const char *data;
 };
 
 
index fba57e6..aee105b 100644 (file)
@@ -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;