X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fp2p%2Fp2p.c;h=122c121776039ed21e58088fbb8295d99c70bf9c;hb=7861cb08c9bca55c195fcd5a9472d0c3db6c040c;hp=ab2f4e5d8b25c089b3279d876c7e1612164d75db;hpb=f7a6905735fb99fec48fdab4c3a1daf9b014c374;p=libeap.git diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index ab2f4e5..122c121 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -419,10 +419,12 @@ static int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr, * Returns: 0 on success, -1 on failure * * If the scan result is for a GO, the clients in the group will also be added - * to the peer table. + * to the peer table. This function can also be used with some other frames + * like Provision Discovery Request that contains P2P Capability and P2P Device + * Info attributes. */ -static int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, - int level, const u8 *ies, size_t ies_len) +int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level, + const u8 *ies, size_t ies_len) { struct p2p_device *dev; struct p2p_message msg; @@ -498,6 +500,8 @@ static int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, msg.ds_params ? *msg.ds_params : -1); } dev->listen_freq = freq; + if (msg.group_info) + dev->oper_freq = freq; dev->level = level; if (msg.pri_dev_type) @@ -793,29 +797,27 @@ void p2p_stop_find(struct p2p_data *p2p) } -int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, - enum p2p_wps_method wps_method, - int go_intent, const u8 *own_interface_addr, - unsigned int force_freq, int persistent_group) +static int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq) { - struct p2p_device *dev; - - wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, - "P2P: Request to start group negotiation - peer=" MACSTR - " GO Intent=%d Intended Interface Address=" MACSTR - " wps_method=%d persistent_group=%d", - MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), - wps_method, persistent_group); - if (force_freq) { + u8 op_reg_class, op_channel; if (p2p_freq_to_channel(p2p->cfg->country, force_freq, - &p2p->op_reg_class, &p2p->op_channel) < - 0) { + &op_reg_class, &op_channel) < 0) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unsupported frequency %u MHz", force_freq); return -1; } + if (!p2p_channels_includes(&p2p->cfg->channels, op_reg_class, + op_channel)) { + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, + "P2P: Frequency %u MHz (oper_class %u " + "channel %u) not allowed for P2P", + force_freq, op_reg_class, op_channel); + return -1; + } + p2p->op_reg_class = op_reg_class; + p2p->op_channel = op_channel; p2p->channels.reg_classes = 1; p2p->channels.reg_class[0].channels = 1; p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; @@ -832,6 +834,27 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, p2p->op_reg_class, p2p->op_channel, force_freq ? " (forced)" : ""); + return 0; +} + + +int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, + enum p2p_wps_method wps_method, + int go_intent, const u8 *own_interface_addr, + unsigned int force_freq, int persistent_group) +{ + struct p2p_device *dev; + + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, + "P2P: Request to start group negotiation - peer=" MACSTR + " GO Intent=%d Intended Interface Address=" MACSTR + " wps_method=%d persistent_group=%d", + MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), + wps_method, persistent_group); + + if (p2p_prepare_channel(p2p, force_freq) < 0) + return -1; + dev = p2p_get_device(p2p, peer_addr); if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, @@ -914,30 +937,8 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), wps_method, persistent_group); - if (force_freq) { - if (p2p_freq_to_channel(p2p->cfg->country, force_freq, - &p2p->op_reg_class, &p2p->op_channel) < - 0) { - wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, - "P2P: Unsupported frequency %u MHz", - force_freq); - return -1; - } - p2p->channels.reg_classes = 1; - p2p->channels.reg_class[0].channels = 1; - p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; - p2p->channels.reg_class[0].channel[0] = p2p->op_channel; - } else { - p2p->op_reg_class = p2p->cfg->op_reg_class; - p2p->op_channel = p2p->cfg->op_channel; - os_memcpy(&p2p->channels, &p2p->cfg->channels, - sizeof(struct p2p_channels)); - } - wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, - "P2P: Own preference for operation channel: " - "Regulatory Class %u Channel %u%s", - p2p->op_reg_class, p2p->op_channel, - force_freq ? " (forced)" : ""); + if (p2p_prepare_channel(p2p, force_freq) < 0) + return -1; dev = p2p_get_device(p2p, peer_addr); if (dev == NULL) { @@ -1090,8 +1091,13 @@ void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); res.ssid_len = p2p->ssid_len; p2p_random(res.passphrase, 8); - } else + } else { res.freq = peer->oper_freq; + if (p2p->ssid_len) { + os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); + res.ssid_len = p2p->ssid_len; + } + } p2p_channels_intersect(&p2p->channels, &peer->channels, &intersection); @@ -1112,6 +1118,8 @@ void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) } } + res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout; + p2p_clear_timeout(p2p); peer->go_neg_req_sent = 0; peer->wps_method = WPS_NOT_READY; @@ -2061,6 +2069,10 @@ static void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: GO Negotiation Response (failure) TX callback: " "success=%d", success); + if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) { + p2p_go_neg_failed(p2p, p2p->go_neg_peer, + p2p->go_neg_peer->status); + } } @@ -3005,3 +3017,22 @@ void p2p_set_cross_connect(struct p2p_data *p2p, int enabled) p2p->cross_connect = enabled; /* TODO: may need to tear down any action group where we are GO(?) */ } + + +int p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr) +{ + struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); + if (dev == NULL) + return -1; + if (dev->oper_freq <= 0) + return -1; + return dev->oper_freq; +} + + +void p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled) +{ + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Intra BSS distribution %s", + enabled ? "enabled" : "disabled"); + p2p->cfg->p2p_intra_bss = enabled; +}