Interworking: Add optional freq argument to INTERWORKING_SELECT
This can be used to limit which channels are scanned using the specified list of frequency ranges in the same format that the SCAN command uses. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
a09ffd5f2f
commit
356d1488c4
3 changed files with 74 additions and 32 deletions
|
@ -4664,7 +4664,68 @@ static int p2p_ctrl_remove_client(struct wpa_supplicant *wpa_s, const char *cmd)
|
|||
#endif /* CONFIG_P2P */
|
||||
|
||||
|
||||
static int * freq_range_to_channel_list(struct wpa_supplicant *wpa_s, char *val)
|
||||
{
|
||||
struct wpa_freq_range_list ranges;
|
||||
int *freqs = NULL;
|
||||
struct hostapd_hw_modes *mode;
|
||||
u16 i;
|
||||
|
||||
if (wpa_s->hw.modes == NULL)
|
||||
return NULL;
|
||||
|
||||
os_memset(&ranges, 0, sizeof(ranges));
|
||||
if (freq_range_list_parse(&ranges, val) < 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < wpa_s->hw.num_modes; i++) {
|
||||
int j;
|
||||
|
||||
mode = &wpa_s->hw.modes[i];
|
||||
for (j = 0; j < mode->num_channels; j++) {
|
||||
unsigned int freq;
|
||||
|
||||
if (mode->channels[j].flag & HOSTAPD_CHAN_DISABLED)
|
||||
continue;
|
||||
|
||||
freq = mode->channels[j].freq;
|
||||
if (!freq_range_list_includes(&ranges, freq))
|
||||
continue;
|
||||
|
||||
int_array_add_unique(&freqs, freq);
|
||||
}
|
||||
}
|
||||
|
||||
os_free(ranges.range);
|
||||
return freqs;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
|
||||
static int ctrl_interworking_select(struct wpa_supplicant *wpa_s, char *param)
|
||||
{
|
||||
int auto_sel = 0;
|
||||
int *freqs = NULL;
|
||||
|
||||
if (param) {
|
||||
char *pos;
|
||||
|
||||
auto_sel = os_strstr(param, "auto") != NULL;
|
||||
|
||||
pos = os_strstr(param, "freq=");
|
||||
if (pos) {
|
||||
freqs = freq_range_to_channel_list(wpa_s, pos + 5);
|
||||
if (freqs == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return interworking_select(wpa_s, auto_sel, freqs);
|
||||
}
|
||||
|
||||
|
||||
static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst)
|
||||
{
|
||||
u8 bssid[ETH_ALEN];
|
||||
|
@ -5413,37 +5474,12 @@ static void wpas_ctrl_eapol_response(void *eloop_ctx, void *timeout_ctx)
|
|||
|
||||
static int set_scan_freqs(struct wpa_supplicant *wpa_s, char *val)
|
||||
{
|
||||
struct wpa_freq_range_list ranges;
|
||||
int *freqs = NULL;
|
||||
struct hostapd_hw_modes *mode;
|
||||
u16 i;
|
||||
|
||||
if (wpa_s->hw.modes == NULL)
|
||||
freqs = freq_range_to_channel_list(wpa_s, val);
|
||||
if (freqs == NULL)
|
||||
return -1;
|
||||
|
||||
os_memset(&ranges, 0, sizeof(ranges));
|
||||
if (freq_range_list_parse(&ranges, val) < 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < wpa_s->hw.num_modes; i++) {
|
||||
int j;
|
||||
|
||||
mode = &wpa_s->hw.modes[i];
|
||||
for (j = 0; j < mode->num_channels; j++) {
|
||||
unsigned int freq;
|
||||
|
||||
if (mode->channels[j].flag & HOSTAPD_CHAN_DISABLED)
|
||||
continue;
|
||||
|
||||
freq = mode->channels[j].freq;
|
||||
if (!freq_range_list_includes(&ranges, freq))
|
||||
continue;
|
||||
|
||||
int_array_add_unique(&freqs, freq);
|
||||
}
|
||||
}
|
||||
|
||||
os_free(ranges.range);
|
||||
os_free(wpa_s->manual_scan_freqs);
|
||||
wpa_s->manual_scan_freqs = freqs;
|
||||
|
||||
|
@ -5847,9 +5883,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
|||
reply_len = -1;
|
||||
} else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) {
|
||||
interworking_stop_fetch_anqp(wpa_s);
|
||||
} else if (os_strncmp(buf, "INTERWORKING_SELECT", 19) == 0) {
|
||||
if (interworking_select(wpa_s, os_strstr(buf + 19, "auto") !=
|
||||
NULL) < 0)
|
||||
} else if (os_strcmp(buf, "INTERWORKING_SELECT") == 0) {
|
||||
if (ctrl_interworking_select(wpa_s, NULL) < 0)
|
||||
reply_len = -1;
|
||||
} else if (os_strncmp(buf, "INTERWORKING_SELECT ", 20) == 0) {
|
||||
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)
|
||||
|
|
|
@ -2202,7 +2202,8 @@ static void interworking_scan_res_handler(struct wpa_supplicant *wpa_s,
|
|||
}
|
||||
|
||||
|
||||
int interworking_select(struct wpa_supplicant *wpa_s, int auto_select)
|
||||
int interworking_select(struct wpa_supplicant *wpa_s, int auto_select,
|
||||
int *freqs)
|
||||
{
|
||||
interworking_stop_fetch_anqp(wpa_s);
|
||||
wpa_s->network_select = 1;
|
||||
|
@ -2214,6 +2215,8 @@ int interworking_select(struct wpa_supplicant *wpa_s, int auto_select)
|
|||
wpa_s->scan_res_handler = interworking_scan_res_handler;
|
||||
wpa_s->normal_scans = 0;
|
||||
wpa_s->scan_req = MANUAL_SCAN_REQ;
|
||||
os_free(wpa_s->manual_scan_freqs);
|
||||
wpa_s->manual_scan_freqs = freqs;
|
||||
wpa_s->after_wps = 0;
|
||||
wpa_s->known_wps_freq = 0;
|
||||
wpa_supplicant_req_scan(wpa_s, 0, 0);
|
||||
|
|
|
@ -22,7 +22,8 @@ int gas_send_request(struct wpa_supplicant *wpa_s, const u8 *dst,
|
|||
const struct wpabuf *query);
|
||||
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 interworking_select(struct wpa_supplicant *wpa_s, int auto_select,
|
||||
int *freqs);
|
||||
int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss);
|
||||
void interworking_start_fetch_anqp(struct wpa_supplicant *wpa_s);
|
||||
int interworking_home_sp_cred(struct wpa_supplicant *wpa_s,
|
||||
|
|
Loading…
Reference in a new issue