P2P NFC: Add processing of P2P client while NFC handover case

Instead of automatically triggering a connection, provide an indication
of one of the devices being a P2P client to upper layers to allow user
to determine what to do next.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2013-04-04 16:18:46 +03:00 committed by Jouni Malinen
parent 74df9ecd4a
commit 59b45d1afe
4 changed files with 109 additions and 60 deletions

View file

@ -151,6 +151,8 @@ extern "C" {
#define P2P_EVENT_PERSISTENT_PSK_FAIL "P2P-PERSISTENT-PSK-FAIL id="
#define P2P_EVENT_PRESENCE_RESPONSE "P2P-PRESENCE-RESPONSE "
#define P2P_EVENT_NFC_BOTH_GO "P2P-NFC-BOTH-GO "
#define P2P_EVENT_NFC_PEER_CLIENT "P2P-NFC-PEER-CLIENT "
#define P2P_EVENT_NFC_WHILE_CLIENT "P2P-NFC-WHILE-CLIENT "
/* parameters: <PMF enabled> <timeout in ms> <Session Information URL> */
#define ESS_DISASSOC_IMMINENT "ESS-DISASSOC-IMMINENT "

View file

@ -4379,7 +4379,8 @@ void p2p_err(struct p2p_data *p2p, const char *fmt, ...)
#ifdef CONFIG_WPS_NFC
static struct wpabuf * p2p_build_nfc_handover(struct p2p_data *p2p)
static struct wpabuf * p2p_build_nfc_handover(struct p2p_data *p2p,
int client_freq)
{
struct wpabuf *buf;
u8 op_class, channel;
@ -4400,6 +4401,9 @@ static struct wpabuf * p2p_build_nfc_handover(struct p2p_data *p2p)
role = P2P_GO_IN_A_GROUP;
p2p_freq_to_channel(p2p_group_get_freq(p2p->groups[0]),
&op_class, &channel);
} else if (client_freq > 0) {
role = P2P_CLIENT_IN_A_GROUP;
p2p_freq_to_channel(client_freq, &op_class, &channel);
}
p2p_buf_add_oob_go_neg_channel(buf, p2p->cfg->country, op_class,
@ -4415,15 +4419,17 @@ static struct wpabuf * p2p_build_nfc_handover(struct p2p_data *p2p)
}
struct wpabuf * p2p_build_nfc_handover_req(struct p2p_data *p2p)
struct wpabuf * p2p_build_nfc_handover_req(struct p2p_data *p2p,
int client_freq)
{
return p2p_build_nfc_handover(p2p);
return p2p_build_nfc_handover(p2p, client_freq);
}
struct wpabuf * p2p_build_nfc_handover_sel(struct p2p_data *p2p)
struct wpabuf * p2p_build_nfc_handover_sel(struct p2p_data *p2p,
int client_freq)
{
return p2p_build_nfc_handover(p2p);
return p2p_build_nfc_handover(p2p, client_freq);
}
@ -4433,7 +4439,8 @@ int p2p_process_nfc_connection_handover(struct p2p_data *p2p,
struct p2p_message msg;
struct p2p_device *dev;
const u8 *p2p_dev_addr;
int peer_go = 0;
int freq;
enum p2p_role_indication role;
params->next_step = NO_ACTION;
@ -4472,37 +4479,38 @@ int p2p_process_nfc_connection_handover(struct p2p_data *p2p,
dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY);
p2p_copy_wps_info(p2p, dev, 0, &msg);
if (msg.oob_go_neg_channel) {
int freq;
if (msg.oob_go_neg_channel[3] == 0 &&
msg.oob_go_neg_channel[4] == 0)
freq = 0;
else
freq = p2p_channel_to_freq(msg.oob_go_neg_channel[3],
msg.oob_go_neg_channel[4]);
if (freq < 0) {
p2p_dbg(p2p, "Unknown peer OOB GO Neg channel");
} else {
p2p_dbg(p2p, "Peer OOB GO Neg channel: %u MHz", freq);
dev->oob_go_neg_freq = freq;
}
if (!params->sel) {
freq = p2p_channel_to_freq(p2p->cfg->reg_class,
p2p->cfg->channel);
if (freq < 0) {
p2p_dbg(p2p, "Own listen channel not known");
return -1;
}
p2p_dbg(p2p, "Use own Listen channel as OOB GO Neg channel: %u MHz",
freq);
dev->oob_go_neg_freq = freq;
}
if (msg.oob_go_neg_channel[5] == P2P_GO_IN_A_GROUP)
peer_go = 1;
if (!msg.oob_go_neg_channel) {
p2p_dbg(p2p, "OOB GO Negotiation Channel attribute not included");
return -1;
}
if (msg.oob_go_neg_channel[3] == 0 &&
msg.oob_go_neg_channel[4] == 0)
freq = 0;
else
freq = p2p_channel_to_freq(msg.oob_go_neg_channel[3],
msg.oob_go_neg_channel[4]);
if (freq < 0) {
p2p_dbg(p2p, "Unknown peer OOB GO Neg channel");
return -1;
} else {
p2p_dbg(p2p, "Peer OOB GO Neg channel: %u MHz", freq);
dev->oob_go_neg_freq = freq;
}
if (!params->sel) {
freq = p2p_channel_to_freq(p2p->cfg->reg_class,
p2p->cfg->channel);
if (freq < 0) {
p2p_dbg(p2p, "Own listen channel not known");
return -1;
}
p2p_dbg(p2p, "Use own Listen channel as OOB GO Neg channel: %u MHz", freq);
dev->oob_go_neg_freq = freq;
}
role = msg.oob_go_neg_channel[5];
p2p_parse_free(&msg);
if (dev->flags & P2P_DEV_USER_REJECTED) {
@ -4516,11 +4524,14 @@ int p2p_process_nfc_connection_handover(struct p2p_data *p2p,
dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
}
if (peer_go && p2p->num_groups > 0)
if (role == P2P_GO_IN_A_GROUP && p2p->num_groups > 0)
params->next_step = BOTH_GO;
else if (peer_go)
else if (role == P2P_GO_IN_A_GROUP)
params->next_step = JOIN_GROUP;
else if (p2p->num_groups > 0)
else if (role == P2P_CLIENT_IN_A_GROUP) {
dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY;
params->next_step = PEER_CLIENT;
} else if (p2p->num_groups > 0)
params->next_step = AUTH_JOIN;
else if (params->sel)
params->next_step = INIT_GO_NEG;

View file

@ -1899,8 +1899,10 @@ int p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int,
*/
const char * p2p_get_state_txt(struct p2p_data *p2p);
struct wpabuf * p2p_build_nfc_handover_req(struct p2p_data *p2p);
struct wpabuf * p2p_build_nfc_handover_sel(struct p2p_data *p2p);
struct wpabuf * p2p_build_nfc_handover_req(struct p2p_data *p2p,
int client_freq);
struct wpabuf * p2p_build_nfc_handover_sel(struct p2p_data *p2p,
int client_freq);
struct p2p_nfc_params {
int sel;
@ -1911,7 +1913,7 @@ struct p2p_nfc_params {
enum {
NO_ACTION, JOIN_GROUP, AUTH_JOIN, INIT_GO_NEG, RESP_GO_NEG,
BOTH_GO
BOTH_GO, PEER_CLIENT
} next_step;
struct p2p_peer_info *peer;
u8 oob_dev_pw[WPS_OOB_PUBKEY_HASH_LEN + 2 +