hostapd: Add MBO IE to BSS Transition Management Request frame
Add an option to add MBO IE to BSS Transition Management Request frame. The MBO IE includes the transition reason code, cellular data connection preference, and, if the disassoc imminent bit is set, it may also include re-association retry delay. Otherwise, the re-association retry delay should be set to zero. The additional BSS_TM_REQ argument uses the following format: mbo=<reason>:<reassoc delay>:<cell pref> reason: 0-9 reassoc delay: 0-65535 (seconds; 0 = disabled) cell pref: 0, 1, 255 Signed-off-by: Avraham Stern <avraham.stern@intel.com>
This commit is contained in:
parent
fb9a1c3e28
commit
c0e2a172a7
3 changed files with 69 additions and 4 deletions
|
@ -884,6 +884,8 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
|
||||||
int ret;
|
int ret;
|
||||||
u8 nei_rep[1000];
|
u8 nei_rep[1000];
|
||||||
u8 *nei_pos = nei_rep;
|
u8 *nei_pos = nei_rep;
|
||||||
|
u8 mbo[10];
|
||||||
|
size_t mbo_len = 0;
|
||||||
|
|
||||||
if (hwaddr_aton(cmd, addr)) {
|
if (hwaddr_aton(cmd, addr)) {
|
||||||
wpa_printf(MSG_DEBUG, "Invalid STA MAC address");
|
wpa_printf(MSG_DEBUG, "Invalid STA MAC address");
|
||||||
|
@ -1049,10 +1051,66 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
|
||||||
if (os_strstr(cmd, " disassoc_imminent=1"))
|
if (os_strstr(cmd, " disassoc_imminent=1"))
|
||||||
req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT;
|
req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT;
|
||||||
|
|
||||||
|
#ifdef CONFIG_MBO
|
||||||
|
pos = os_strstr(cmd, "mbo=");
|
||||||
|
if (pos) {
|
||||||
|
unsigned int mbo_reason, cell_pref, reassoc_delay;
|
||||||
|
u8 *mbo_pos = mbo;
|
||||||
|
|
||||||
|
ret = sscanf(pos, "mbo=%u:%u:%u", &mbo_reason,
|
||||||
|
&reassoc_delay, &cell_pref);
|
||||||
|
if (ret != 3) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MBO requires three arguments: mbo=<reason>:<reassoc_delay>:<cell_pref>");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbo_reason > MBO_TRANSITION_REASON_PREMIUM_AP) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"Invalid MBO transition reason code %u",
|
||||||
|
mbo_reason);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Valid values for Cellular preference are: 0, 1, 255 */
|
||||||
|
if (cell_pref != 0 && cell_pref != 1 && cell_pref != 255) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"Invalid MBO cellular capability %u",
|
||||||
|
cell_pref);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reassoc_delay > 65535 ||
|
||||||
|
(reassoc_delay &&
|
||||||
|
!(req_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT))) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MBO: Assoc retry delay is only valid in disassoc imminent mode");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*mbo_pos++ = MBO_ATTR_ID_TRANSITION_REASON;
|
||||||
|
*mbo_pos++ = 1;
|
||||||
|
*mbo_pos++ = mbo_reason;
|
||||||
|
*mbo_pos++ = MBO_ATTR_ID_CELL_DATA_PREF;
|
||||||
|
*mbo_pos++ = 1;
|
||||||
|
*mbo_pos++ = cell_pref;
|
||||||
|
|
||||||
|
if (reassoc_delay) {
|
||||||
|
*mbo_pos++ = MBO_ATTR_ID_ASSOC_RETRY_DELAY;
|
||||||
|
*mbo_pos++ = 2;
|
||||||
|
WPA_PUT_LE16(mbo_pos, reassoc_delay);
|
||||||
|
mbo_pos += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbo_len = mbo_pos - mbo;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_MBO */
|
||||||
|
|
||||||
ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer,
|
ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer,
|
||||||
valid_int, bss_term_dur, url,
|
valid_int, bss_term_dur, url,
|
||||||
nei_pos > nei_rep ? nei_rep : NULL,
|
nei_pos > nei_rep ? nei_rep : NULL,
|
||||||
nei_pos - nei_rep);
|
nei_pos - nei_rep, mbo_len ? mbo : NULL,
|
||||||
|
mbo_len);
|
||||||
os_free(url);
|
os_free(url);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -527,7 +527,8 @@ int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd,
|
||||||
int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
|
int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
u8 req_mode, int disassoc_timer, u8 valid_int,
|
u8 req_mode, int disassoc_timer, u8 valid_int,
|
||||||
const u8 *bss_term_dur, const char *url,
|
const u8 *bss_term_dur, const char *url,
|
||||||
const u8 *nei_rep, size_t nei_rep_len)
|
const u8 *nei_rep, size_t nei_rep_len,
|
||||||
|
const u8 *mbo_attrs, size_t mbo_len)
|
||||||
{
|
{
|
||||||
u8 *buf, *pos;
|
u8 *buf, *pos;
|
||||||
struct ieee80211_mgmt *mgmt;
|
struct ieee80211_mgmt *mgmt;
|
||||||
|
@ -536,7 +537,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
|
wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
|
||||||
MACSTR " req_mode=0x%x disassoc_timer=%d valid_int=0x%x",
|
MACSTR " req_mode=0x%x disassoc_timer=%d valid_int=0x%x",
|
||||||
MAC2STR(sta->addr), req_mode, disassoc_timer, valid_int);
|
MAC2STR(sta->addr), req_mode, disassoc_timer, valid_int);
|
||||||
buf = os_zalloc(1000 + nei_rep_len);
|
buf = os_zalloc(1000 + nei_rep_len + mbo_len);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
mgmt = (struct ieee80211_mgmt *) buf;
|
mgmt = (struct ieee80211_mgmt *) buf;
|
||||||
|
@ -579,6 +580,11 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
pos += nei_rep_len;
|
pos += nei_rep_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mbo_len > 0) {
|
||||||
|
pos += mbo_add_ie(pos, buf + sizeof(buf) - pos, mbo_attrs,
|
||||||
|
mbo_len);
|
||||||
|
}
|
||||||
|
|
||||||
if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0) < 0) {
|
if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0) < 0) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"Failed to send BSS Transition Management Request frame");
|
"Failed to send BSS Transition Management Request frame");
|
||||||
|
|
|
@ -21,6 +21,7 @@ int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd,
|
||||||
int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
|
int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
u8 req_mode, int disassoc_timer, u8 valid_int,
|
u8 req_mode, int disassoc_timer, u8 valid_int,
|
||||||
const u8 *bss_term_dur, const char *url,
|
const u8 *bss_term_dur, const char *url,
|
||||||
const u8 *nei_rep, size_t nei_rep_len);
|
const u8 *nei_rep, size_t nei_rep_len,
|
||||||
|
const u8 *mbo_attrs, size_t mbo_len);
|
||||||
|
|
||||||
#endif /* WNM_AP_H */
|
#endif /* WNM_AP_H */
|
||||||
|
|
Loading…
Reference in a new issue