Add ctrl_iface command for triggering a roam to a specific BSS
'wpa_cli roam <bssid>' can now be used to test roaming within an ESS (e.g., for FT over-the-air). This command will bypass a new scan and will select the BSS based on the specified BSSID. It is responsibility of the caller to make sure that the target AP is in the BSS table. This can be done, e.g., by running a scan before the roam command, if needed.
This commit is contained in:
parent
a7b6c42232
commit
86d4f806da
4 changed files with 72 additions and 3 deletions
|
@ -1648,6 +1648,46 @@ static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
|
|||
}
|
||||
|
||||
|
||||
static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
|
||||
char *addr)
|
||||
{
|
||||
u8 bssid[ETH_ALEN];
|
||||
struct wpa_bss *bss;
|
||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
|
||||
if (hwaddr_aton(addr, bssid)) {
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
|
||||
"address '%s'", addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid));
|
||||
|
||||
bss = wpa_bss_get_bssid(wpa_s, bssid);
|
||||
if (!bss) {
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found "
|
||||
"from BSS table");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Find best network configuration block from configuration to
|
||||
* allow roaming to other networks
|
||||
*/
|
||||
|
||||
if (!ssid) {
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network "
|
||||
"configuration known for the target AP");
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_s->reassociate = 1;
|
||||
wpa_supplicant_connect(wpa_s, bss, ssid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||
char *buf, size_t *resp_len)
|
||||
{
|
||||
|
@ -1853,6 +1893,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
|||
wpas_notify_resume(wpa_s->global);
|
||||
} else if (os_strcmp(buf, "DROP_SA") == 0) {
|
||||
wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
|
||||
} else if (os_strncmp(buf, "ROAM ", 5) == 0) {
|
||||
if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5))
|
||||
reply_len = -1;
|
||||
} else {
|
||||
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
|
||||
reply_len = 16;
|
||||
|
|
|
@ -720,7 +720,7 @@ static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
|
|||
}
|
||||
|
||||
|
||||
static void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
|
||||
void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_bss *selected,
|
||||
struct wpa_ssid *ssid)
|
||||
{
|
||||
|
|
|
@ -1440,6 +1440,26 @@ static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
|||
}
|
||||
|
||||
|
||||
static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||
{
|
||||
char cmd[128];
|
||||
int res;
|
||||
|
||||
if (argc != 1) {
|
||||
printf("Invalid ROAM command: needs one argument "
|
||||
"(target AP's BSSID)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
|
||||
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
||||
printf("Too long ROAM command.\n");
|
||||
return -1;
|
||||
}
|
||||
return wpa_ctrl_command(ctrl, cmd);
|
||||
}
|
||||
|
||||
|
||||
enum wpa_cli_cmd_flags {
|
||||
cli_cmd_flag_none = 0x00,
|
||||
cli_cmd_flag_sensitive = 0x01
|
||||
|
@ -1640,6 +1660,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
|
|||
"= notification of resume/thaw" },
|
||||
{ "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
|
||||
"= drop SA without deauth/disassoc (test command)" },
|
||||
{ "roam", wpa_cli_cmd_roam,
|
||||
cli_cmd_flag_none,
|
||||
"<addr> = roam to the specified BSS" },
|
||||
{ NULL, NULL, cli_cmd_flag_none, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -488,6 +488,9 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
|
|||
|
||||
/* events.c */
|
||||
void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s);
|
||||
void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_bss *selected,
|
||||
struct wpa_ssid *ssid);
|
||||
|
||||
/* eap_register.c */
|
||||
int eap_register_methods(void);
|
||||
|
|
Loading…
Reference in a new issue