"go_dev_addr=" MACSTR,
MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr));
- return group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP;
+ return !!(group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP);
}
int client;
int persistent;
u8 go_dev_addr[ETH_ALEN];
- int network_id = -1;
/*
* This callback is likely called for the main interface. Update wpa_s
}
if (persistent)
- network_id = wpas_p2p_store_persistent_group(wpa_s->p2pdev,
- ssid, go_dev_addr);
+ wpas_p2p_store_persistent_group(wpa_s->p2pdev,
+ ssid, go_dev_addr);
else {
os_free(wpa_s->global->add_psk);
wpa_s->global->add_psk = NULL;
}
- if (network_id < 0 && ssid)
- network_id = ssid->id;
+
if (!client) {
- wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
+ wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 0);
os_get_reltime(&wpa_s->global->p2p_go_wait_client);
}
}
struct wpa_supplicant *wpa_s = ctx;
struct p2p_go_neg_results *params = data;
struct wpa_ssid *ssid;
- int network_id = -1;
wpa_s->ap_configured_cb = NULL;
wpa_s->ap_configured_cb_ctx = NULL;
os_get_reltime(&wpa_s->global->p2p_go_wait_client);
if (params->persistent_group) {
- network_id = wpas_p2p_store_persistent_group(
+ wpas_p2p_store_persistent_group(
wpa_s->p2pdev, ssid,
wpa_s->global->p2p_dev_addr);
wpas_p2p_add_psk_list(wpa_s, ssid);
}
- if (network_id < 0)
- network_id = ssid->id;
- wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
+
+ wpas_notify_p2p_group_started(wpa_s, ssid,
+ params->persistent_group, 0);
wpas_p2p_cross_connect_setup(wpa_s);
wpas_p2p_set_group_idle_timeout(wpa_s);
wpa_config_set_network_defaults(ssid);
ssid->temporary = 1;
ssid->p2p_group = 1;
- ssid->p2p_persistent_group = params->persistent_group;
+ ssid->p2p_persistent_group = !!params->persistent_group;
ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION :
WPAS_MODE_P2P_GO;
ssid->frequency = params->freq;
d = dst->conf;
s = src->conf;
-#define C(n) if (s->n) d->n = os_strdup(s->n)
+#define C(n) \
+do { \
+ if (s->n && !d->n) \
+ d->n = os_strdup(s->n); \
+} while (0)
+
C(device_name);
C(manufacturer);
C(model_name);
d->disable_scan_offload = s->disable_scan_offload;
d->passive_scan = s->passive_scan;
- if (s->wps_nfc_dh_privkey && s->wps_nfc_dh_pubkey) {
- d->wps_nfc_dh_privkey = wpabuf_dup(s->wps_nfc_dh_privkey);
- d->wps_nfc_dh_pubkey = wpabuf_dup(s->wps_nfc_dh_pubkey);
- }
- d->p2p_cli_probe = s->p2p_cli_probe;
-}
-
-
-static void wpas_p2p_clone_config_dh(struct wpa_supplicant *dst,
- const struct wpa_supplicant *src)
-{
- struct wpa_config *d;
- const struct wpa_config *s;
-
- d = dst->conf;
- s = src->conf;
-
if (s->wps_nfc_dh_privkey && s->wps_nfc_dh_pubkey &&
- !d->wps_nfc_dh_privkey && !d->wps_nfc_dh_pubkey) {
+ !d->wps_nfc_pw_from_config) {
+ wpabuf_free(d->wps_nfc_dh_privkey);
+ wpabuf_free(d->wps_nfc_dh_pubkey);
d->wps_nfc_dh_privkey = wpabuf_dup(s->wps_nfc_dh_privkey);
d->wps_nfc_dh_pubkey = wpabuf_dup(s->wps_nfc_dh_pubkey);
}
+ d->p2p_cli_probe = s->p2p_cli_probe;
}
group_wpa_s = wpa_s->parent;
wpa_s->global->p2p_group_formation = group_wpa_s;
if (group_wpa_s != wpa_s)
- wpas_p2p_clone_config_dh(group_wpa_s, wpa_s);
+ wpas_p2p_clone_config(group_wpa_s, wpa_s);
}
group_wpa_s->p2p_in_provisioning = 1;
u8 channel)
{
u8 center_channels[] = { 42, 58, 106, 122, 138, 155 };
- unsigned int i;
+ size_t i;
if (mode->mode != HOSTAPD_MODE_IEEE80211A)
return 0;
wpa_s->p2p_pin[sizeof(wpa_s->p2p_pin) - 1] = '\0';
wpa_printf(MSG_DEBUG, "P2P: Randomly generated PIN: %s",
wpa_s->p2p_pin);
+ } else if (wps_method == WPS_P2PS) {
+ /* Force the P2Ps default PIN to be used */
+ os_strlcpy(wpa_s->p2p_pin, "12345670", sizeof(wpa_s->p2p_pin));
} else
wpa_s->p2p_pin[0] = '\0';
"P2P: Use primary interface for group operations");
wpa_s->p2p_first_connection_timeout = 0;
if (wpa_s != wpa_s->p2pdev)
- wpas_p2p_clone_config_dh(wpa_s, wpa_s->p2pdev);
+ wpas_p2p_clone_config(wpa_s, wpa_s->p2pdev);
return wpa_s;
}
struct p2p_group *group;
struct p2p_group_config *cfg;
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
+ if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
+ !ssid->p2p_group)
return NULL;
cfg = os_zalloc(sizeof(*cfg));
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1;
+ if (wpa_s->p2p_lo_started) {
+ wpa_printf(MSG_DEBUG,
+ "P2P: Cannot start P2P listen, it is offloaded");
+ return -1;
+ }
+
wpa_supplicant_cancel_sched_scan(wpa_s);
wpas_p2p_clear_pending_action_tx(wpa_s);
return 0;
switch (p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid,
- ie, ie_len, rx_freq)) {
+ ie, ie_len, rx_freq, wpa_s->p2p_lo_started)) {
case P2P_PREQ_NOT_P2P:
wpas_notify_preq(wpa_s, addr, dst, bssid, ie, ie_len,
ssi_signal);
{
struct wpa_ssid *ssid = wpa_s->current_ssid;
u8 go_dev_addr[ETH_ALEN];
- int network_id = -1;
int persistent;
int freq;
u8 ip[3 * 4];
ip_addr);
if (persistent)
- network_id = wpas_p2p_store_persistent_group(wpa_s->p2pdev,
- ssid, go_dev_addr);
- if (network_id < 0)
- network_id = ssid->id;
- wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 1);
+ wpas_p2p_store_persistent_group(wpa_s->p2pdev,
+ ssid, go_dev_addr);
+
+ wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 1);
}
wpa_s->ap_iface->bss[0]->p2p_group = NULL;
wpas_p2p_group_deinit(wpa_s);
}
+
+
+int wpas_p2p_lo_start(struct wpa_supplicant *wpa_s, unsigned int freq,
+ unsigned int period, unsigned int interval,
+ unsigned int count)
+{
+ struct p2p_data *p2p = wpa_s->global->p2p;
+ u8 *device_types;
+ size_t dev_types_len;
+ struct wpabuf *buf;
+ int ret;
+
+ if (wpa_s->p2p_lo_started) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "P2P Listen offload is already started");
+ return 0;
+ }
+
+ if (wpa_s->global->p2p == NULL ||
+ !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_LISTEN_OFFLOAD)) {
+ wpa_printf(MSG_DEBUG, "P2P: Listen offload not supported");
+ return -1;
+ }
+
+ if (!p2p_supported_freq(wpa_s->global->p2p, freq)) {
+ wpa_printf(MSG_ERROR, "P2P: Input channel not supported: %u",
+ freq);
+ return -1;
+ }
+
+ /* Get device type */
+ dev_types_len = (wpa_s->conf->num_sec_device_types + 1) *
+ WPS_DEV_TYPE_LEN;
+ device_types = os_malloc(dev_types_len);
+ if (!device_types)
+ return -1;
+ os_memcpy(device_types, wpa_s->conf->device_type, WPS_DEV_TYPE_LEN);
+ os_memcpy(&device_types[WPS_DEV_TYPE_LEN], wpa_s->conf->sec_device_type,
+ wpa_s->conf->num_sec_device_types * WPS_DEV_TYPE_LEN);
+
+ /* Get Probe Response IE(s) */
+ buf = p2p_build_probe_resp_template(p2p, freq);
+ if (!buf) {
+ os_free(device_types);
+ return -1;
+ }
+
+ ret = wpa_drv_p2p_lo_start(wpa_s, freq, period, interval, count,
+ device_types, dev_types_len,
+ wpabuf_mhead_u8(buf), wpabuf_len(buf));
+ if (ret < 0)
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "P2P: Failed to start P2P listen offload");
+
+ os_free(device_types);
+ wpabuf_free(buf);
+
+ if (ret == 0) {
+ wpa_s->p2p_lo_started = 1;
+
+ /* Stop current P2P listen if any */
+ wpas_stop_listen(wpa_s);
+ }
+
+ return ret;
+}
+
+
+int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s)
+{
+ int ret;
+
+ if (!wpa_s->p2p_lo_started)
+ return 0;
+
+ ret = wpa_drv_p2p_lo_stop(wpa_s);
+ if (ret < 0)
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "P2P: Failed to stop P2P listen offload");
+
+ wpa_s->p2p_lo_started = 0;
+ return ret;
+}