[PATCH 12/23] P2PS: Add channel policy to PD request
Ilan Peer
ilan.peer
Thu Sep 24 10:38:02 PDT 2015
Add operating channel selection and channel list processing
similar to that done when build GON request, i.e., consider the
currently used channels, configured channels etc.
P2PS introduces a flow where a responder needs to provide
channel data without being previously aware of the current
constraints, i.e., the channels currently in use by other
interfaces. To handle this, extend the get_group_capability()
callback to also handle channels selection aspects of
group capabilities.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/p2p/p2p.c | 8 +++---
src/p2p/p2p.h | 26 +++++++++++++++-----
src/p2p/p2p_pd.c | 54 +++++++++++++++++++++++------------------
wpa_supplicant/p2p_supplicant.c | 24 ++++++++++++++++--
4 files changed, 76 insertions(+), 36 deletions(-)
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 53527f4..a6002f7 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -1459,7 +1459,7 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
/**
- * p2p_prepare_channel - Select operating channel for GO Negotiation
+ * p2p_prepare_channel - Select operating channel for GO Negotiation or P2PS PD
* @p2p: P2P module context from p2p_init()
* @dev: Selected peer device
* @force_freq: Forced frequency in MHz or 0 if not forced
@@ -1468,9 +1468,9 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
* Returns: 0 on success, -1 on failure (channel not supported for P2P)
*
* This function is used to do initial operating channel selection for GO
- * Negotiation prior to having received peer information. The selected channel
- * may be further optimized in p2p_reselect_channel() once the peer information
- * is available.
+ * Negotiation prior to having received peer information or for P2PS PD
+ * signalling. The selected channel may be further optimized in
+ * p2p_reselect_channel() once the peer information is available.
*/
int p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev,
unsigned int force_freq, unsigned int pref_freq, int go)
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index b4060be..8f7e19b 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -224,6 +224,16 @@ struct p2ps_provision {
u8 cpt_priority[P2PS_FEATURE_CAPAB_CPT_MAX + 1];
/**
+ * force_freq - the only allowed channel frequency in MHz or 0.
+ */
+ int force_freq;
+
+ /**
+ * pref_freq - preferred operating frequency in MHz or 0.
+ */
+ int pref_freq;
+
+ /**
* info - Vendor defined extra Provisioning information
*/
char info[0];
@@ -1070,14 +1080,18 @@ struct p2p_config {
/**
* p2ps_group_capability - Determine group capability
+ * @incoming: peer requested roles, expressed with P2PS_SETUP* bitmap.
+ * @role: local roles, expressed with P2PS_SETUP* bitmap.
+ * @force_freq: variable for returning forced frequency for the group.
+ * @pref_freq: variable for returning preferred frequency for the group.
+ * Returns: P2PS_SETUP_* bitmap of group capability result.
*
- * This function can be used to determine group capability based on
- * information from P2PS PD exchange and the current state of ongoing
- * groups and driver capabilities.
- *
- * P2PS_SETUP_* bitmap is used as the parameters and return value.
+ * This function can be used to determine group capability and
+ * frequencies based on information from P2PS PD exchange and the
+ * current state of ongoing groups and driver capabilities.
*/
- u8 (*p2ps_group_capability)(void *ctx, u8 incoming, u8 role);
+ u8 (*p2ps_group_capability)(void *ctx, u8 incoming, u8 role,
+ int *force_freq, int *pref_freq);
/**
* get_pref_freq_list - Get preferred frequency list for an interface
diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index b96b125..d354f76 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -109,25 +109,18 @@ static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
go_dev_addr, ssid, &ssid_len, intended_addr);
}
- /* Add Operating Channel if conncap includes GO */
if (shared_group ||
- (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
- P2PS_SETUP_NEW))) {
- u8 tmp;
-
- p2p_go_select_channel(p2p, dev, &tmp);
-
- if (p2p->op_reg_class && p2p->op_channel)
- p2p_buf_add_operating_channel(buf, p2p->cfg->country,
- p2p->op_reg_class,
- p2p->op_channel);
- else
- p2p_buf_add_operating_channel(buf, p2p->cfg->country,
- p2p->cfg->op_reg_class,
- p2p->cfg->op_channel);
- }
+ (prov->conncap & P2PS_SETUP_CLIENT) ||
+ (prov->conncap & P2PS_SETUP_NEW))
+ p2p_buf_add_channel_list(buf, p2p->cfg->country,
+ &p2p->channels);
- p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->cfg->channels);
+ if ((shared_group && !is_zero_ether_addr(intended_addr)) ||
+ (prov->conncap & P2PS_SETUP_GROUP_OWNER) ||
+ (prov->conncap & P2PS_SETUP_NEW))
+ p2p_buf_add_operating_channel(buf, p2p->cfg->country,
+ p2p->op_reg_class,
+ p2p->op_channel);
if (prov->info[0])
p2p_buf_add_session_info(buf, prov->info);
@@ -345,7 +338,7 @@ static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
}
p2p_buf_add_channel_list(buf, p2p->cfg->country,
- &p2p->cfg->channels);
+ &p2p->channels);
if (!persist && (status == P2P_SC_SUCCESS ||
status == P2P_SC_SUCCESS_DEFERRED))
@@ -701,9 +694,14 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
}
if (p2ps_adv) {
+ int forced_freq, pref_freq;
+
auto_accept = p2ps_adv->auto_accept;
conncap = p2p->cfg->p2ps_group_capability(
- p2p->cfg->cb_ctx, conncap, auto_accept);
+ p2p->cfg->cb_ctx, conncap, auto_accept,
+ &forced_freq, &pref_freq);
+
+ p2p_prepare_channel(p2p, dev, forced_freq, pref_freq, 0);
p2p_dbg(p2p, "Conncap: local:%d remote:%d result:%d",
auto_accept, remote_conncap, conncap);
@@ -754,6 +752,8 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
}
tmp = p2p->p2ps_prov;
+ tmp->force_freq = forced_freq;
+ tmp->pref_freq = pref_freq;
if (conncap) {
tmp->conncap = conncap;
tmp->status = P2P_SC_SUCCESS;
@@ -816,12 +816,9 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
conncap = p2p->cfg->p2ps_group_capability(
p2p->cfg->cb_ctx, remote_conncap,
- p2p->p2ps_prov->conncap);
-
- p2p_dbg(p2p,
- "Conncap: local:%d remote:%d result:%d",
p2p->p2ps_prov->conncap,
- remote_conncap, conncap);
+ &p2p->p2ps_prov->force_freq,
+ &p2p->p2ps_prov->pref_freq);
resp_fcap.cpt = p2ps_own_preferred_cpt(
p2p->p2ps_prov->cpt_priority,
@@ -832,6 +829,11 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
p2p->p2ps_prov->cpt_mask,
req_fcap->cpt, resp_fcap.cpt);
+ p2p_prepare_channel(p2p, dev,
+ p2p->p2ps_prov->force_freq,
+ p2p->p2ps_prov->pref_freq,
+ 0);
+
/*
* Ensure that if we asked for PIN originally,
* our method is consistent with original
@@ -1466,6 +1468,10 @@ int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
"Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x",
p2p->p2ps_prov->method, p2p->p2ps_prov->status,
dev->req_config_methods);
+
+ if (p2p_prepare_channel(p2p, dev, p2p->p2ps_prov->force_freq,
+ p2p->p2ps_prov->pref_freq, 1) < 0)
+ return -1;
}
req = p2p_build_prov_disc_req(p2p, dev, join);
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 5b98b69..be71fce 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -117,6 +117,10 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
int go);
static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
const u8 *ssid, size_t ssid_len);
+static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
+ int *force_freq, int *pref_freq, int go,
+ unsigned int *pref_freq_list,
+ unsigned int *num_pref_freq);
static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
const u8 *ssid, size_t ssid_len);
static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx);
@@ -633,7 +637,8 @@ wpas_p2p_get_persistent_go(struct wpa_supplicant *wpa_s)
}
-static u8 p2ps_group_capability(void *ctx, u8 incoming, u8 role)
+static u8 p2ps_group_capability(void *ctx, u8 incoming, u8 role,
+ int *force_freq, int *pref_freq)
{
struct wpa_supplicant *wpa_s = ctx;
struct wpa_ssid *s;
@@ -645,6 +650,19 @@ static u8 p2ps_group_capability(void *ctx, u8 incoming, u8 role)
wpa_printf(MSG_DEBUG, "P2P: Conncap - in:%d role:%d", incoming, role);
+ if (force_freq && pref_freq) {
+ unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
+ *force_freq = 0;
+ *pref_freq = 0;
+
+ if (!wpas_p2p_setup_freqs(wpa_s, 0, force_freq, pref_freq, 0,
+ pref_freq_list, &size))
+ wpas_p2p_set_own_freq_preference(wpa_s,
+ *force_freq ?
+ *force_freq :
+ *pref_freq);
+ }
+
/*
* For non-concurrent capable devices:
* If persistent_go, then no new.
@@ -6188,7 +6206,9 @@ int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
wpa_s->pending_pd_use = NORMAL_PD;
if (p2ps_prov && use == WPAS_P2P_PD_FOR_ASP) {
p2ps_prov->conncap = p2ps_group_capability(
- wpa_s, P2PS_SETUP_NONE, p2ps_prov->role);
+ wpa_s, P2PS_SETUP_NONE, p2ps_prov->role,
+ &p2ps_prov->force_freq, &p2ps_prov->pref_freq);
+
wpa_printf(MSG_DEBUG,
"P2P: %s conncap: %d - ASP parsed: %x %x %d %s",
__func__, p2ps_prov->conncap,
--
1.9.1
More information about the Hostap
mailing list