From 65833d71a5f3b8240db397efa7200e894a3eab1f Mon Sep 17 00:00:00 2001 From: Ashwini Patil Date: Fri, 16 Jun 2017 17:47:03 +0530 Subject: [PATCH] OCE: Add hostapd mode OCE capability indication if enabled Add OCE IE in Beacon, Probe Response, and (Re)Association Response frames if OCE is enabled in the configuration. Signed-off-by: Jouni Malinen --- hostapd/config_file.c | 2 ++ hostapd/hostapd.conf | 9 ++++++++ hostapd/main.c | 23 ++++++++++++++++++-- src/ap/ap_config.h | 7 +++++++ src/ap/ap_drv_ops.c | 2 +- src/ap/hostapd.h | 5 +++++ src/ap/ieee802_11_shared.c | 43 ++++++++++++++++++++++++++++++-------- src/common/defs.h | 1 + 8 files changed, 80 insertions(+), 12 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 14d4ee720..dfe8ab794 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -3488,6 +3488,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, bss->mbo_enabled = atoi(pos); } else if (os_strcmp(buf, "mbo_cell_data_conn_pref") == 0) { bss->mbo_cell_data_conn_pref = atoi(pos); + } else if (os_strcmp(buf, "oce") == 0) { + bss->oce = atoi(pos); #endif /* CONFIG_MBO */ #ifdef CONFIG_TESTING_OPTIONS #define PARSE_TEST_PROBABILITY(_val) \ diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 980c138d6..51c47e698 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -2091,6 +2091,15 @@ own_ip_addr=127.0.0.1 # 255 = AP prefers the STA to use cellular data connection #mbo_cell_data_conn_pref=1 +##### Optimized Connectivity Experience (OCE) ################################# +# +# Enable OCE specific features (bitmap) +# BIT(0) - Reserved +# Set BIT(1) (= 2) to enable OCE in STA-CFON mode +# Set BIT(2) (= 4) to enable OCE in AP mode +# Default is 0 = OCE disabled +#oce=0 + ##### Fast Session Transfer (FST) support ##################################### # # The options in this section are only available when the build configuration diff --git a/hostapd/main.c b/hostapd/main.c index 785b320bb..ce94d0572 100644 --- a/hostapd/main.c +++ b/hostapd/main.c @@ -869,8 +869,27 @@ int main(int argc, char *argv[]) */ interfaces.terminate_on_error = interfaces.count; for (i = 0; i < interfaces.count; i++) { - if (hostapd_driver_init(interfaces.iface[i]) || - hostapd_setup_interface(interfaces.iface[i])) + if (hostapd_driver_init(interfaces.iface[i])) + goto out; +#ifdef CONFIG_MBO + for (j = 0; j < interfaces.iface[i]->num_bss; j++) { + struct hostapd_data *hapd = interfaces.iface[i]->bss[j]; + + if (hapd && (hapd->conf->oce & OCE_STA_CFON) && + (interfaces.iface[i]->drv_flags & + WPA_DRIVER_FLAGS_OCE_STA_CFON)) + hapd->enable_oce = OCE_STA_CFON; + + if (hapd && (hapd->conf->oce & OCE_AP) && + (interfaces.iface[i]->drv_flags & + WPA_DRIVER_FLAGS_OCE_STA_CFON)) { + /* TODO: Need to add OCE-AP support */ + wpa_printf(MSG_ERROR, + "OCE-AP feature is not yet supported"); + } + } +#endif /* CONFIG_MBO */ + if (hostapd_setup_interface(interfaces.iface[i])) goto out; } diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 14fa23090..8e5ff524d 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -605,6 +605,13 @@ struct hostapd_bss_config { #ifdef CONFIG_MBO int mbo_enabled; + /** + * oce - Enable OCE in AP and/or STA-CFON mode + * - BIT(0) is Reserved + * - Set BIT(1) to enable OCE in STA-CFON mode + * - Set BIT(2) to enable OCE in AP mode + */ + unsigned int oce; int mbo_cell_data_conn_pref; #endif /* CONFIG_MBO */ diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index b3d4f0324..8f4d83984 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -176,7 +176,7 @@ int hostapd_build_ap_extra_ies(struct hostapd_data *hapd, #endif /* CONFIG_HS20 */ #ifdef CONFIG_MBO - if (hapd->conf->mbo_enabled) { + if (hapd->conf->mbo_enabled || hapd->enable_oce) { pos = hostapd_eid_mbo(hapd, buf, sizeof(buf)); if (add_buf_data(&beacon, buf, pos - buf) < 0 || add_buf_data(&proberesp, buf, pos - buf) < 0 || diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 8580d8073..fc19c25a9 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -308,6 +308,11 @@ struct hostapd_data { #ifdef CONFIG_MBO unsigned int mbo_assoc_disallow; + /** + * enable_oce - Enable OCE if it is enabled by user and device also + * supports OCE. + */ + u8 enable_oce; #endif /* CONFIG_MBO */ struct dl_list nr_db; diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c index 4d5ec2f6b..bf6d4cc35 100644 --- a/src/ap/ieee802_11_shared.c +++ b/src/ap/ieee802_11_shared.c @@ -544,23 +544,38 @@ u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid) u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len) { - u8 mbo[6], *mbo_pos = mbo; + u8 mbo[9], *mbo_pos = mbo; u8 *pos = eid; - if (!hapd->conf->mbo_enabled) + if (!hapd->conf->mbo_enabled && !hapd->enable_oce) return eid; - *mbo_pos++ = MBO_ATTR_ID_AP_CAPA_IND; - *mbo_pos++ = 1; - /* Not Cellular aware */ - *mbo_pos++ = 0; + if (hapd->conf->mbo_enabled) { + *mbo_pos++ = MBO_ATTR_ID_AP_CAPA_IND; + *mbo_pos++ = 1; + /* Not Cellular aware */ + *mbo_pos++ = 0; + } - if (hapd->mbo_assoc_disallow) { + if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) { *mbo_pos++ = MBO_ATTR_ID_ASSOC_DISALLOW; *mbo_pos++ = 1; *mbo_pos++ = hapd->mbo_assoc_disallow; } + if (hapd->enable_oce & (OCE_AP | OCE_STA_CFON)) { + u8 ctrl; + + ctrl = OCE_RELEASE; + if ((hapd->enable_oce & (OCE_AP | OCE_STA_CFON)) == + OCE_STA_CFON) + ctrl |= OCE_IS_STA_CFON; + + *mbo_pos++ = OCE_ATTR_ID_CAPA_IND; + *mbo_pos++ = 1; + *mbo_pos++ = ctrl; + } + pos += mbo_add_ie(pos, len, mbo, mbo_pos - mbo); return pos; @@ -569,14 +584,24 @@ u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len) u8 hostapd_mbo_ie_len(struct hostapd_data *hapd) { - if (!hapd->conf->mbo_enabled) + u8 len; + + if (!hapd->conf->mbo_enabled && !hapd->enable_oce) return 0; /* * MBO IE header (6) + Capability Indication attribute (3) + * Association Disallowed attribute (3) = 12 */ - return 6 + 3 + (hapd->mbo_assoc_disallow ? 3 : 0); + len = 6; + if (hapd->conf->mbo_enabled) + len += 3 + (hapd->mbo_assoc_disallow ? 3 : 0); + + /* OCE capability indication attribute (3) */ + if (hapd->enable_oce & (OCE_AP | OCE_STA_CFON)) + len += 3; + + return len; } #endif /* CONFIG_MBO */ diff --git a/src/common/defs.h b/src/common/defs.h index f15c5cc32..1de099f4b 100644 --- a/src/common/defs.h +++ b/src/common/defs.h @@ -391,5 +391,6 @@ enum eap_proxy_sim_state { #define OCE_STA BIT(0) #define OCE_STA_CFON BIT(1) +#define OCE_AP BIT(2) #endif /* DEFS_H */