* 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;
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)
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);
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);
+ }
}
p2p_ext_listen_timeout, p2p, NULL);
}
+ if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) {
+ /*
+ * This should not really happen, but it looks like the Listen
+ * command may fail is something else (e.g., a scan) was
+ * running at an inconvenient time. As a workaround, allow new
+ * Extended Listen operation to be started.
+ */
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Previous "
+ "Extended Listen operation had not been completed - "
+ "try again");
+ p2p->ext_listen_only = 0;
+ p2p_set_state(p2p, P2P_IDLE);
+ }
+
if (p2p->state != P2P_IDLE) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip Extended "
"Listen timeout in active state (%s)",
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;
+}