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 =
|
||||
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_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_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 */
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
char *buf, size_t len);
|
||||
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,
|
||||
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->sae_groups);
|
||||
wpabuf_free(config->ap_vendor_elements);
|
||||
wpabuf_free(config->ap_assocresp_elements);
|
||||
os_free(config->osu_dir);
|
||||
os_free(config->bgscan);
|
||||
os_free(config->wowlan_triggers);
|
||||
|
@ -4913,9 +4914,9 @@ static int wpa_config_process_ap_vendor_elements(
|
|||
u8 *p;
|
||||
|
||||
if (!len) {
|
||||
wpa_printf(MSG_ERROR, "Line %d: invalid ap_vendor_elements",
|
||||
line);
|
||||
return -1;
|
||||
wpabuf_free(config->ap_vendor_elements);
|
||||
config->ap_vendor_elements = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
static int wpa_config_process_no_ctrl_interface(
|
||||
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(dtim_period), 0 },
|
||||
{ INT(beacon_int), 0 },
|
||||
{ FUNC(ap_assocresp_elements), 0 },
|
||||
{ FUNC(ap_vendor_elements), 0 },
|
||||
{ INT_RANGE(ignore_old_scan_res, 0, 1), 0 },
|
||||
{ FUNC(freq_list), 0 },
|
||||
|
|
|
@ -1241,6 +1241,17 @@ struct wpa_config {
|
|||
*/
|
||||
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
|
||||
*
|
||||
|
|
|
@ -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)
|
||||
fprintf(f, "ignore_old_scan_res=%d\n",
|
||||
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) {
|
||||
if (wpas_ap_stop_ap(wpa_s))
|
||||
reply_len = -1;
|
||||
} else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {
|
||||
if (wpas_ap_update_beacon(wpa_s))
|
||||
reply_len = -1;
|
||||
#endif /* CONFIG_AP */
|
||||
} else if (os_strcmp(buf, "SUSPEND") == 0) {
|
||||
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",
|
||||
"preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
|
||||
"reassoc_same_bss_optim", "wps_priority",
|
||||
"ap_assocresp_elements",
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
"ignore_auth_resp",
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
|
@ -3563,6 +3571,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
|
|||
"<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
|
||||
" [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
|
||||
" = CSA parameters" },
|
||||
{ "update_beacon", wpa_cli_cmd_update_beacon, NULL,
|
||||
cli_cmd_flag_none,
|
||||
"= update Beacon frame contents"},
|
||||
#endif /* CONFIG_AP */
|
||||
{ "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
|
||||
"= notification of suspend/hibernate" },
|
||||
|
|
Loading…
Reference in a new issue