Support vendor element configuration for AP mode from wpa_supplicant
Support adding/deleting vendor elements dynamically for AP mode while it is started by wpa_supplicant instead of hostapd which already supported this. This adds ap_assocresp_elements global parameter and UPDATE_BEACON control interface command to take the changed values into effect. Usage in wpa_cli: Add vendor IE for (Re)Association Response frames > set ap_assocresp_elements=xxxx Add vendor IE for Beacon/Probe Response frames > set ap_vendor_elements=xxxx Delete vendor IE from (Re)Association Response frames > set ap_assocresp_elements Delete vendor IE from Beacon/Probe Response frames > set ap_vendor_elements To make vendor IE changes take effect > update_beacon Signed-off-by: Chaoli Zhou <zchaoli@codeaurora.org>
This commit is contained in:
parent
7dc0e9cf47
commit
9651deba52
7 changed files with 98 additions and 3 deletions
|
@ -763,6 +763,10 @@ no_wps:
|
||||||
bss->vendor_elements =
|
bss->vendor_elements =
|
||||||
wpabuf_dup(wpa_s->conf->ap_vendor_elements);
|
wpabuf_dup(wpa_s->conf->ap_vendor_elements);
|
||||||
}
|
}
|
||||||
|
if (wpa_s->conf->ap_assocresp_elements) {
|
||||||
|
bss->assocresp_elements =
|
||||||
|
wpabuf_dup(wpa_s->conf->ap_assocresp_elements);
|
||||||
|
}
|
||||||
|
|
||||||
bss->ftm_responder = wpa_s->conf->ftm_responder;
|
bss->ftm_responder = wpa_s->conf->ftm_responder;
|
||||||
bss->ftm_initiator = wpa_s->conf->ftm_initiator;
|
bss->ftm_initiator = wpa_s->conf->ftm_initiator;
|
||||||
|
@ -1813,6 +1817,32 @@ int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
#endif /* CONFIG_MESH */
|
#endif /* CONFIG_MESH */
|
||||||
#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
|
#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
|
||||||
|
|
||||||
|
|
||||||
|
int wpas_ap_update_beacon(struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
struct hostapd_data *hapd;
|
||||||
|
|
||||||
|
if (!wpa_s->ap_iface)
|
||||||
|
return -1;
|
||||||
|
hapd = wpa_s->ap_iface->bss[0];
|
||||||
|
|
||||||
|
wpabuf_free(hapd->conf->assocresp_elements);
|
||||||
|
hapd->conf->assocresp_elements = NULL;
|
||||||
|
if (wpa_s->conf->ap_assocresp_elements) {
|
||||||
|
hapd->conf->assocresp_elements =
|
||||||
|
wpabuf_dup(wpa_s->conf->ap_assocresp_elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
wpabuf_free(hapd->conf->vendor_elements);
|
||||||
|
hapd->conf->vendor_elements = NULL;
|
||||||
|
if (wpa_s->conf->ap_vendor_elements) {
|
||||||
|
hapd->conf->vendor_elements =
|
||||||
|
wpabuf_dup(wpa_s->conf->ap_vendor_elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ieee802_11_set_beacon(hapd);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_CTRL_IFACE */
|
#endif /* CONFIG_CTRL_IFACE */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ void wpas_ap_pmksa_cache_flush(struct wpa_supplicant *wpa_s);
|
||||||
int wpas_ap_pmksa_cache_list_mesh(struct wpa_supplicant *wpa_s, const u8 *addr,
|
int wpas_ap_pmksa_cache_list_mesh(struct wpa_supplicant *wpa_s, const u8 *addr,
|
||||||
char *buf, size_t len);
|
char *buf, size_t len);
|
||||||
int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd);
|
int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd);
|
||||||
|
int wpas_ap_update_beacon(struct wpa_supplicant *wpa_s);
|
||||||
|
|
||||||
void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
|
void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
|
||||||
struct dfs_event *radar);
|
struct dfs_event *radar);
|
||||||
|
|
|
@ -2951,6 +2951,7 @@ void wpa_config_free(struct wpa_config *config)
|
||||||
os_free(config->ext_password_backend);
|
os_free(config->ext_password_backend);
|
||||||
os_free(config->sae_groups);
|
os_free(config->sae_groups);
|
||||||
wpabuf_free(config->ap_vendor_elements);
|
wpabuf_free(config->ap_vendor_elements);
|
||||||
|
wpabuf_free(config->ap_assocresp_elements);
|
||||||
os_free(config->osu_dir);
|
os_free(config->osu_dir);
|
||||||
os_free(config->bgscan);
|
os_free(config->bgscan);
|
||||||
os_free(config->wowlan_triggers);
|
os_free(config->wowlan_triggers);
|
||||||
|
@ -4913,9 +4914,9 @@ static int wpa_config_process_ap_vendor_elements(
|
||||||
u8 *p;
|
u8 *p;
|
||||||
|
|
||||||
if (!len) {
|
if (!len) {
|
||||||
wpa_printf(MSG_ERROR, "Line %d: invalid ap_vendor_elements",
|
wpabuf_free(config->ap_vendor_elements);
|
||||||
line);
|
config->ap_vendor_elements = NULL;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = wpabuf_alloc(len);
|
tmp = wpabuf_alloc(len);
|
||||||
|
@ -4941,6 +4942,31 @@ static int wpa_config_process_ap_vendor_elements(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_config_process_ap_assocresp_elements(
|
||||||
|
const struct global_parse_data *data,
|
||||||
|
struct wpa_config *config, int line, const char *pos)
|
||||||
|
{
|
||||||
|
struct wpabuf *tmp;
|
||||||
|
|
||||||
|
if (!*pos) {
|
||||||
|
wpabuf_free(config->ap_assocresp_elements);
|
||||||
|
config->ap_assocresp_elements = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = wpabuf_parse_bin(pos);
|
||||||
|
if (!tmp) {
|
||||||
|
wpa_printf(MSG_ERROR, "Line %d: invalid ap_assocresp_elements",
|
||||||
|
line);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
wpabuf_free(config->ap_assocresp_elements);
|
||||||
|
config->ap_assocresp_elements = tmp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_CTRL_IFACE
|
#ifdef CONFIG_CTRL_IFACE
|
||||||
static int wpa_config_process_no_ctrl_interface(
|
static int wpa_config_process_no_ctrl_interface(
|
||||||
const struct global_parse_data *data,
|
const struct global_parse_data *data,
|
||||||
|
@ -5155,6 +5181,7 @@ static const struct global_parse_data global_fields[] = {
|
||||||
{ INT_RANGE(sae_pmkid_in_assoc, 0, 1), 0 },
|
{ INT_RANGE(sae_pmkid_in_assoc, 0, 1), 0 },
|
||||||
{ INT(dtim_period), 0 },
|
{ INT(dtim_period), 0 },
|
||||||
{ INT(beacon_int), 0 },
|
{ INT(beacon_int), 0 },
|
||||||
|
{ FUNC(ap_assocresp_elements), 0 },
|
||||||
{ FUNC(ap_vendor_elements), 0 },
|
{ FUNC(ap_vendor_elements), 0 },
|
||||||
{ INT_RANGE(ignore_old_scan_res, 0, 1), 0 },
|
{ INT_RANGE(ignore_old_scan_res, 0, 1), 0 },
|
||||||
{ FUNC(freq_list), 0 },
|
{ FUNC(freq_list), 0 },
|
||||||
|
|
|
@ -1241,6 +1241,17 @@ struct wpa_config {
|
||||||
*/
|
*/
|
||||||
struct wpabuf *ap_vendor_elements;
|
struct wpabuf *ap_vendor_elements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ap_assocresp_elements: Vendor specific elements for (Re)Association
|
||||||
|
* Response frames
|
||||||
|
*
|
||||||
|
* This parameter can be used to define additional vendor specific
|
||||||
|
* elements for (Re)Association Response frames in AP/P2P GO mode. The
|
||||||
|
* format for these element(s) is a hexdump of the raw information
|
||||||
|
* elements (id+len+payload for one or more elements).
|
||||||
|
*/
|
||||||
|
struct wpabuf *ap_assocresp_elements;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ignore_old_scan_res - Ignore scan results older than request
|
* ignore_old_scan_res - Ignore scan results older than request
|
||||||
*
|
*
|
||||||
|
|
|
@ -1364,6 +1364,18 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config->ap_assocresp_elements) {
|
||||||
|
int i, len = wpabuf_len(config->ap_assocresp_elements);
|
||||||
|
const u8 *p = wpabuf_head_u8(config->ap_assocresp_elements);
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
fprintf(f, "ap_assocresp_elements=");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
fprintf(f, "%02x", *p++);
|
||||||
|
fprintf(f, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (config->ignore_old_scan_res)
|
if (config->ignore_old_scan_res)
|
||||||
fprintf(f, "ignore_old_scan_res=%d\n",
|
fprintf(f, "ignore_old_scan_res=%d\n",
|
||||||
config->ignore_old_scan_res);
|
config->ignore_old_scan_res);
|
||||||
|
|
|
@ -12055,6 +12055,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
} else if (os_strcmp(buf, "STOP_AP") == 0) {
|
} else if (os_strcmp(buf, "STOP_AP") == 0) {
|
||||||
if (wpas_ap_stop_ap(wpa_s))
|
if (wpas_ap_stop_ap(wpa_s))
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
|
} else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {
|
||||||
|
if (wpas_ap_update_beacon(wpa_s))
|
||||||
|
reply_len = -1;
|
||||||
#endif /* CONFIG_AP */
|
#endif /* CONFIG_AP */
|
||||||
} else if (os_strcmp(buf, "SUSPEND") == 0) {
|
} else if (os_strcmp(buf, "SUSPEND") == 0) {
|
||||||
wpas_notify_suspend(wpa_s->global);
|
wpas_notify_suspend(wpa_s->global);
|
||||||
|
|
|
@ -499,6 +499,7 @@ static char ** wpa_cli_complete_set(const char *str, int pos)
|
||||||
"p2p_search_delay", "mac_addr", "rand_addr_lifetime",
|
"p2p_search_delay", "mac_addr", "rand_addr_lifetime",
|
||||||
"preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
|
"preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
|
||||||
"reassoc_same_bss_optim", "wps_priority",
|
"reassoc_same_bss_optim", "wps_priority",
|
||||||
|
"ap_assocresp_elements",
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
"ignore_auth_resp",
|
"ignore_auth_resp",
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
@ -2037,6 +2038,13 @@ static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
|
||||||
return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
|
return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
return wpa_ctrl_command(ctrl, "UPDATE_BEACON");
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_AP */
|
#endif /* CONFIG_AP */
|
||||||
|
|
||||||
|
|
||||||
|
@ -3563,6 +3571,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
|
||||||
"<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
|
"<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
|
||||||
" [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
|
" [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
|
||||||
" = CSA parameters" },
|
" = CSA parameters" },
|
||||||
|
{ "update_beacon", wpa_cli_cmd_update_beacon, NULL,
|
||||||
|
cli_cmd_flag_none,
|
||||||
|
"= update Beacon frame contents"},
|
||||||
#endif /* CONFIG_AP */
|
#endif /* CONFIG_AP */
|
||||||
{ "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
|
{ "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
|
||||||
"= notification of suspend/hibernate" },
|
"= notification of suspend/hibernate" },
|
||||||
|
|
Loading…
Reference in a new issue