diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index a6ebe3b2b..0162b6c51 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -5946,7 +5946,8 @@ static int ctrl_interworking_select(struct wpa_supplicant *wpa_s, char *param) } -static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst) +static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst, + int only_add) { u8 bssid[ETH_ALEN]; struct wpa_bss *bss; @@ -5984,7 +5985,7 @@ static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst) "Found another matching BSS entry with SSID"); } - return interworking_connect(wpa_s, bss); + return interworking_connect(wpa_s, bss, only_add); } @@ -8119,8 +8120,19 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, if (ctrl_interworking_select(wpa_s, buf + 20) < 0) reply_len = -1; } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) { - if (ctrl_interworking_connect(wpa_s, buf + 21) < 0) + if (ctrl_interworking_connect(wpa_s, buf + 21, 0) < 0) reply_len = -1; + } else if (os_strncmp(buf, "INTERWORKING_ADD_NETWORK ", 25) == 0) { + int id; + + id = ctrl_interworking_connect(wpa_s, buf + 25, 1); + if (id < 0) + reply_len = -1; + else { + reply_len = os_snprintf(reply, reply_size, "%d\n", id); + if (os_snprintf_error(reply_size, reply_len)) + reply_len = -1; + } } else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) { if (get_anqp(wpa_s, buf + 9) < 0) reply_len = -1; diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 5b66211a5..0bffe3473 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -955,7 +955,7 @@ static int interworking_set_hs20_params(struct wpa_supplicant *wpa_s, static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s, struct wpa_cred *cred, - struct wpa_bss *bss) + struct wpa_bss *bss, int only_add) { #ifdef INTERWORKING_3GPP struct wpa_ssid *ssid; @@ -972,7 +972,7 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s, if (already_connected(wpa_s, cred, bss)) { wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR, MAC2STR(bss->bssid)); - return 0; + return wpa_s->current_ssid->id; } remove_duplicate_network(wpa_s, cred, bss); @@ -1049,9 +1049,10 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s, wpa_s->next_ssid = ssid; wpa_config_update_prio_list(wpa_s->conf); - interworking_reconnect(wpa_s); + if (!only_add) + interworking_reconnect(wpa_s); - return 0; + return ssid->id; fail: wpas_notify_network_removed(wpa_s, ssid); @@ -1499,7 +1500,7 @@ static int interworking_set_eap_params(struct wpa_ssid *ssid, static int interworking_connect_roaming_consortium( struct wpa_supplicant *wpa_s, struct wpa_cred *cred, - struct wpa_bss *bss) + struct wpa_bss *bss, int only_add) { struct wpa_ssid *ssid; @@ -1509,7 +1510,7 @@ static int interworking_connect_roaming_consortium( if (already_connected(wpa_s, cred, bss)) { wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR, MAC2STR(bss->bssid)); - return 0; + return wpa_s->current_ssid->id; } remove_duplicate_network(wpa_s, cred, bss); @@ -1545,9 +1546,10 @@ static int interworking_connect_roaming_consortium( wpa_s->next_ssid = ssid; wpa_config_update_prio_list(wpa_s->conf); - interworking_reconnect(wpa_s); + if (!only_add) + interworking_reconnect(wpa_s); - return 0; + return ssid->id; fail: wpas_notify_network_removed(wpa_s, ssid); @@ -1557,7 +1559,8 @@ fail: static int interworking_connect_helper(struct wpa_supplicant *wpa_s, - struct wpa_bss *bss, int allow_excluded) + struct wpa_bss *bss, int allow_excluded, + int only_add) { struct wpa_cred *cred, *cred_rc, *cred_3gpp; struct wpa_ssid *ssid; @@ -1659,11 +1662,12 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, (cred == NULL || cred_prio_cmp(cred_rc, cred) >= 0) && (cred_3gpp == NULL || cred_prio_cmp(cred_rc, cred_3gpp) >= 0)) return interworking_connect_roaming_consortium(wpa_s, cred_rc, - bss); + bss, only_add); if (cred_3gpp && (cred == NULL || cred_prio_cmp(cred_3gpp, cred) >= 0)) { - return interworking_connect_3gpp(wpa_s, cred_3gpp, bss); + return interworking_connect_3gpp(wpa_s, cred_3gpp, bss, + only_add); } if (cred == NULL) { @@ -1801,9 +1805,10 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, wpa_s->next_ssid = ssid; wpa_config_update_prio_list(wpa_s->conf); - interworking_reconnect(wpa_s); + if (!only_add) + interworking_reconnect(wpa_s); - return 0; + return ssid->id; fail: wpas_notify_network_removed(wpa_s, ssid); @@ -1813,9 +1818,10 @@ fail: } -int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) +int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, + int only_add) { - return interworking_connect_helper(wpa_s, bss, 1); + return interworking_connect_helper(wpa_s, bss, 1, only_add); } @@ -2495,7 +2501,7 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s) MAC2STR(selected->bssid)); wpa_msg(wpa_s, MSG_INFO, INTERWORKING_SELECTED MACSTR, MAC2STR(selected->bssid)); - interworking_connect(wpa_s, selected); + interworking_connect(wpa_s, selected, 0); } } diff --git a/wpa_supplicant/interworking.h b/wpa_supplicant/interworking.h index 38ef745fa..3743dc00e 100644 --- a/wpa_supplicant/interworking.h +++ b/wpa_supplicant/interworking.h @@ -24,7 +24,8 @@ int interworking_fetch_anqp(struct wpa_supplicant *wpa_s); void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s); int interworking_select(struct wpa_supplicant *wpa_s, int auto_select, int *freqs); -int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss); +int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, + int only_add); void interworking_start_fetch_anqp(struct wpa_supplicant *wpa_s); int interworking_home_sp_cred(struct wpa_supplicant *wpa_s, struct wpa_cred *cred, diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 2f06c35ae..af08e1303 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -2309,6 +2309,13 @@ static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc, } +static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv); +} + + static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) { return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv); @@ -2997,6 +3004,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { { "interworking_connect", wpa_cli_cmd_interworking_connect, wpa_cli_complete_bss, cli_cmd_flag_none, " = connect using Interworking credentials" }, + { "interworking_add_network", wpa_cli_cmd_interworking_add_network, + wpa_cli_complete_bss, cli_cmd_flag_none, + " = connect using Interworking credentials" }, { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss, cli_cmd_flag_none, " [,]... = request ANQP information" },