<h3>RemoveAllCreds ( ) --> nothing</h3>
<p>Remove all configured Interworking/Hotspot 2.0 credentials.</p>
</li>
+ <li>
+ <h3>InterworkingSelect ( ) --> nothing</h3>
+ <p>Perform Interworking (Hotspot 2.0) network selection.</p>
+ </li>
<li>
<h3>EAPLogoff ( ) --> nothing</h3>
<p>IEEE 802.1X EAPOL state machine logoff.</p>
<dd>A dictionary with pairs of field names and their values. Possible dictionary keys are: "addr", "dst", "bssid", "ies", "signal".</dd>
</dl>
</li>
+
+ <li>
+ <h3>InterworkingAPAdded ( o : bss, o : cred, a{sv} : args )</h3>
+ </li>
+
+ <li>
+ <h3>InterworkingSelectDone ( )</h3>
+ </li>
</ul>
raise Exception("Credential remove failed")
if not "FAIL" in dev[0].get_cred(1, 'domain'):
raise Exception("Credential remove failed")
+
+def test_dbus_interworking(dev, apdev):
+ "D-Bus interworking selection"
+ (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
+ iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
+
+ params = {"ssid": "test-interworking", "wpa": "2",
+ "wpa_key_mgmt": "WPA-EAP", "rsn_pairwise": "CCMP",
+ "ieee8021x": "1", "eapol_version": "2",
+ "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
+ "ca_cert": "auth_serv/ca.pem",
+ "server_cert": "auth_serv/server.pem",
+ "private_key": "auth_serv/server.key",
+ "interworking": "1",
+ "domain_name": "server.w1.fi",
+ "nai_realm": "0,server.w1.fi,21[2:4][5:7]",
+ "roaming_consortium": "2233445566",
+ "hs20": "1", "anqp_domain_id": "1234"}
+
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ class TestDbusInterworking(TestDbus):
+ def __init__(self, bus):
+ TestDbus.__init__(self, bus)
+ self.interworking_ap_seen = False
+ self.interworking_select_done = False
+
+ def __enter__(self):
+ gobject.timeout_add(1, self.run_select)
+ gobject.timeout_add(15000, self.timeout)
+ self.add_signal(self.interworkingAPAdded, WPAS_DBUS_IFACE,
+ "InterworkingAPAdded")
+ self.add_signal(self.interworkingSelectDone, WPAS_DBUS_IFACE,
+ "InterworkingSelectDone")
+ self.loop.run()
+ return self
+
+ def interworkingAPAdded(self, bss, cred, properties):
+ logger.debug("interworkingAPAdded: bss=%s cred=%s %s" % (bss, cred, str(properties)))
+ if self.cred == cred:
+ self.interworking_ap_seen = True
+
+ def interworkingSelectDone(self):
+ logger.debug("interworkingSelectDone")
+ self.interworking_select_done = True
+ self.loop.quit()
+
+ def run_select(self, *args):
+ args = {"domain": "server.w1.fi",
+ "realm": "server.w1.fi",
+ "eap": "TTLS",
+ "phase2": "auth=MSCHAPV2",
+ "username": "user",
+ "password": "password",
+ "domain_suffix_match": "server.w1.fi",
+ "ca_cert": "auth_serv/ca.pem"}
+ self.cred = iface.AddCred(dbus.Dictionary(args, signature='sv'))
+ iface.InterworkingSelect()
+ return False
+
+ def success(self):
+ return self.interworking_ap_seen and self.interworking_select_done
+
+ with TestDbusInterworking(bus) as t:
+ if not t.success():
+ raise Exception("Expected signals not seen")
#endif /* CONFIG_MESH */
+#ifdef CONFIG_INTERWORKING
+
+void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss,
+ struct wpa_cred *cred,
+ const char *type,
+ int excluded,
+ int bh,
+ int bss_load,
+ int conn_capab)
+{
+ struct wpas_dbus_priv *iface;
+ DBusMessage *msg;
+ DBusMessageIter iter, dict_iter;
+ char bss_path[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path;
+ char cred_path[WPAS_DBUS_OBJECT_PATH_MAX], *cred_obj_path;
+
+ iface = wpa_s->global->dbus;
+
+ /* Do nothing if the control interface is not turned on */
+ if (!iface || !wpa_s->dbus_new_path)
+ return;
+
+ msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE,
+ "InterworkingAPAdded");
+ if (!msg)
+ return;
+
+ os_snprintf(bss_path, WPAS_DBUS_OBJECT_PATH_MAX,
+ "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
+ wpa_s->dbus_new_path, bss->id);
+ bss_obj_path = bss_path;
+
+ os_snprintf(cred_path, WPAS_DBUS_OBJECT_PATH_MAX,
+ "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%u",
+ wpa_s->dbus_new_path, cred->id);
+ cred_obj_path = cred_path;
+
+ dbus_message_iter_init_append(msg, &iter);
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &bss_obj_path) ||
+ !dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &cred_obj_path) ||
+ !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
+ !wpa_dbus_dict_append_string(&dict_iter, "type", type) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "excluded", excluded) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "priority",
+ cred->priority) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "sp_priority",
+ cred->sp_priority) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "below_min_backhaul", bh) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "over_max_bss_load",
+ bss_load) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "conn_capab_missing",
+ conn_capab) ||
+ !wpa_dbus_dict_close_write(&iter, &dict_iter))
+ wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+ else
+ dbus_connection_send(iface->con, msg, NULL);
+ dbus_message_unref(msg);
+}
+
+
+void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s)
+{
+ struct wpas_dbus_priv *iface;
+ DBusMessage *msg;
+
+ iface = wpa_s->global->dbus;
+
+ /* Do nothing if the control interface is not turned on */
+ if (!iface || !wpa_s->dbus_new_path)
+ return;
+
+ msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE,
+ "InterworkingSelectDone");
+ if (!msg)
+ return;
+
+ dbus_connection_send(iface->con, msg, NULL);
+
+ dbus_message_unref(msg);
+}
+
+#endif /* CONFIG_INTERWORKING */
+
+
void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
int depth, const char *subject,
const char *altsubject[],
END_ARGS
}
},
+ { "InterworkingSelect", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) wpas_dbus_handler_interworking_select,
+ {
+ END_ARGS
+ }
+ },
#endif /* CONFIG_INTERWORKING */
{ NULL, NULL, NULL, { END_ARGS } }
};
}
},
#endif /* CONFIG_MESH */
+#ifdef CONFIG_INTERWORKING
+ { "InterworkingAPAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ {
+ { "bss", "o", ARG_OUT },
+ { "cred", "o", ARG_OUT },
+ { "properties", "a{sv}", ARG_OUT },
+ END_ARGS
+ }
+ },
+ { "InterworkingSelectDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ {
+ END_ARGS
+ }
+ },
+#endif /* CONFIG_INTERWORKING */
{ NULL, NULL, { END_ARGS } }
};
struct wpa_global;
struct wpa_supplicant;
struct wpa_ssid;
+struct wpa_cred;
+struct wpa_bss;
struct wps_event_m2d;
struct wps_event_fail;
struct wps_credential;
const u8 *peer_addr);
void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
const u8 *peer_addr, int reason);
+void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss,
+ struct wpa_cred *cred,
+ const char *type, int excluded,
+ int bh, int bss_load,
+ int conn_capab);
+void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s);
#else /* CONFIG_CTRL_IFACE_DBUS_NEW */
{
}
+static inline
+void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss,
+ struct wpa_cred *cred,
+ const char *type, int excluded,
+ int bh, int bss_load,
+ int conn_capab)
+{
+}
+
+static inline
+void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s)
+{
+}
+
#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
#endif /* CTRL_IFACE_DBUS_H_NEW */
#include "../scan.h"
#include "../autoscan.h"
#include "../ap.h"
+#include "../interworking.h"
#include "dbus_new_helpers.h"
#include "dbus_new.h"
#include "dbus_new_handlers.h"
}
+DBusMessage *
+wpas_dbus_handler_interworking_select(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ int result;
+ DBusMessage *reply = NULL;
+
+ /* Automatic selection is disabled and no constraint on channels */
+ result = interworking_select(wpa_s, 0, NULL);
+ if (result < 0) {
+ wpa_printf(MSG_ERROR,
+ "%s[dbus]: failed to start Interworking selection",
+ __func__);
+ reply = wpas_dbus_error_scan_error(
+ message,
+ "error starting Interworking selection.");
+ }
+
+ return reply;
+}
+
+
/**
* wpas_dbus_handler_signal_poll - Request immediate signal properties
* @message: Pointer to incoming dbus message
DBusMessage * wpas_dbus_handler_remove_all_creds(DBusMessage *message,
struct wpa_supplicant *wpa_s);
+DBusMessage *
+wpas_dbus_handler_interworking_select(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
DECLARE_ACCESSOR(wpas_dbus_getter_capabilities);
DECLARE_ACCESSOR(wpas_dbus_getter_state);
DECLARE_ACCESSOR(wpas_dbus_getter_scanning);
bh = cred_below_min_backhaul(wpa_s, cred, bss);
bss_load = cred_over_max_bss_load(wpa_s, cred, bss);
conn_capab = cred_conn_capab_missing(wpa_s, cred, bss);
- wpa_msg(wpa_s, MSG_INFO, "%s" MACSTR " type=%s%s%s%s id=%d priority=%d sp_priority=%d",
- excluded ? INTERWORKING_EXCLUDED : INTERWORKING_AP,
- MAC2STR(bss->bssid), type,
- bh ? " below_min_backhaul=1" : "",
- bss_load ? " over_max_bss_load=1" : "",
- conn_capab ? " conn_capab_missing=1" : "",
- cred->id, cred->priority, cred->sp_priority);
+ wpas_notify_interworking_ap_added(wpa_s, bss, cred, excluded,
+ type, bh, bss_load,
+ conn_capab);
if (excluded)
continue;
if (wpa_s->auto_select ||
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
}
+ wpas_notify_interworking_select_done(wpa_s);
+
if (selected) {
wpa_printf(MSG_DEBUG, "Interworking: Selected " MACSTR,
MAC2STR(selected->bssid));
#include "rsn_supp/wpa.h"
#include "fst/fst.h"
#include "crypto/tls.h"
+#include "bss.h"
#include "driver_i.h"
#include "scan.h"
#include "p2p_supplicant.h"
}
#endif /* CONFIG_MESH */
+
+
+#ifdef CONFIG_INTERWORKING
+
+void wpas_notify_interworking_ap_added(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss,
+ struct wpa_cred *cred, int excluded,
+ const char *type, int bh, int bss_load,
+ int conn_capab)
+{
+ wpa_msg(wpa_s, MSG_INFO, "%s" MACSTR " type=%s%s%s%s id=%d priority=%d sp_priority=%d",
+ excluded ? INTERWORKING_EXCLUDED : INTERWORKING_AP,
+ MAC2STR(bss->bssid), type,
+ bh ? " below_min_backhaul=1" : "",
+ bss_load ? " over_max_bss_load=1" : "",
+ conn_capab ? " conn_capab_missing=1" : "",
+ cred->id, cred->priority, cred->sp_priority);
+
+ wpas_dbus_signal_interworking_ap_added(wpa_s, bss, cred, type, excluded,
+ bh, bss_load, conn_capab);
+}
+
+
+void wpas_notify_interworking_select_done(struct wpa_supplicant *wpa_s)
+{
+ wpas_dbus_signal_interworking_select_done(wpa_s);
+}
+
+#endif /* CONFIG_INTERWORKING */
struct wps_event_m2d;
struct wps_event_fail;
struct tls_cert_data;
+struct wpa_cred;
int wpas_notify_supplicant_initialized(struct wpa_global *global);
void wpas_notify_supplicant_deinitialized(struct wpa_global *global);
const u8 *peer_addr);
void wpas_notify_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
const u8 *peer_addr, u16 reason_code);
+void wpas_notify_interworking_ap_added(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss,
+ struct wpa_cred *cred, int excluded,
+ const char *type, int bh, int bss_load,
+ int conn_capab);
+void wpas_notify_interworking_select_done(struct wpa_supplicant *wpa_s);
#endif /* NOTIFY_H */