mesh: Write close reason from Mesh Peering Close to debug log
[mech_eap.git] / wpa_supplicant / p2p_supplicant.c
index 19c7c75..8c5af5e 100644 (file)
@@ -351,6 +351,7 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
        int social_channels_freq[] = { 2412, 2437, 2462, 60480 };
        size_t ielen;
        u8 *n, i;
+       unsigned int bands;
 
        if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
                return -1;
@@ -429,7 +430,8 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
        wpabuf_put_buf(ies, wps_ie);
        wpabuf_free(wps_ie);
 
-       p2p_scan_ie(wpa_s->global->p2p, ies, dev_id);
+       bands = wpas_get_bands(wpa_s, params->freqs);
+       p2p_scan_ie(wpa_s->global->p2p, ies, dev_id, bands);
 
        params->p2p_probe = 1;
        n = os_malloc(wpabuf_len(ies));
@@ -1132,7 +1134,8 @@ static int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s,
        s->auth_alg = WPA_AUTH_ALG_OPEN;
        s->key_mgmt = WPA_KEY_MGMT_PSK;
        s->proto = WPA_PROTO_RSN;
-       s->pairwise_cipher = WPA_CIPHER_CCMP;
+       s->pbss = ssid->pbss;
+       s->pairwise_cipher = ssid->pbss ? WPA_CIPHER_GCMP : WPA_CIPHER_CCMP;
        s->export_keys = 1;
        if (ssid->passphrase) {
                os_free(s->passphrase);
@@ -1298,7 +1301,6 @@ static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
        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
@@ -1373,16 +1375,15 @@ static void wpas_group_formation_completed(struct wpa_supplicant *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);
        }
 }
@@ -1747,7 +1748,6 @@ static void p2p_go_configured(void *ctx, void *data)
        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;
@@ -1794,14 +1794,14 @@ static void p2p_go_configured(void *ctx, void *data)
 
                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);
 
@@ -1948,7 +1948,12 @@ static void wpas_p2p_clone_config(struct wpa_supplicant *dst,
        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);
@@ -1976,28 +1981,14 @@ static void wpas_p2p_clone_config(struct wpa_supplicant *dst,
        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;
 }
 
 
@@ -2252,7 +2243,7 @@ static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
                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;
@@ -2387,6 +2378,10 @@ static void wpas_dev_lost(void *ctx, const u8 *dev_addr)
 static void wpas_find_stopped(void *ctx)
 {
        struct wpa_supplicant *wpa_s = ctx;
+
+       if (wpa_s->p2p_scan_work && wpas_abort_ongoing_scan(wpa_s) < 0)
+               wpa_printf(MSG_DEBUG, "P2P: Abort ongoing scan failed");
+
        wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_FIND_STOPPED);
        wpas_notify_p2p_find_stopped(wpa_s);
 }
@@ -3011,12 +3006,31 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
                           MAC2STR(sa), op_freq, wpa_ssid_txt(ssid, ssid_len));
                if (s) {
                        int go = s->mode == WPAS_MODE_P2P_GO;
+                       if (go) {
+                               wpa_msg_global(wpa_s, MSG_INFO,
+                                              P2P_EVENT_INVITATION_ACCEPTED
+                                              "sa=" MACSTR
+                                              " persistent=%d freq=%d",
+                                              MAC2STR(sa), s->id, op_freq);
+                       } else {
+                               wpa_msg_global(wpa_s, MSG_INFO,
+                                              P2P_EVENT_INVITATION_ACCEPTED
+                                              "sa=" MACSTR
+                                              " persistent=%d",
+                                              MAC2STR(sa), s->id);
+                       }
                        wpas_p2p_group_add_persistent(
                                wpa_s, s, go, 0, op_freq, 0, 0, 0, 0, NULL,
                                go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
                                1);
                } else if (bssid) {
                        wpa_s->user_initiated_pd = 0;
+                       wpa_msg_global(wpa_s, MSG_INFO,
+                                      P2P_EVENT_INVITATION_ACCEPTED
+                                      "sa=" MACSTR " go_dev_addr=" MACSTR
+                                      " bssid=" MACSTR " unknown-network",
+                                      MAC2STR(sa), MAC2STR(go_dev_addr),
+                                      MAC2STR(bssid));
                        wpas_p2p_join(wpa_s, bssid, go_dev_addr,
                                      wpa_s->p2p_wps_method, 0, op_freq,
                                      ssid, ssid_len);
@@ -4930,6 +4944,7 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
        struct wpabuf *wps_ie, *ies;
        size_t ielen;
        int freqs[2] = { 0, 0 };
+       unsigned int bands;
 
        os_memset(&params, 0, sizeof(params));
 
@@ -4981,7 +4996,8 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
        wpabuf_put_buf(ies, wps_ie);
        wpabuf_free(wps_ie);
 
-       p2p_scan_ie(wpa_s->global->p2p, ies, NULL);
+       bands = wpas_get_bands(wpa_s, freqs);
+       p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
 
        params.p2p_probe = 1;
        params.extra_ies = wpabuf_head(ies);
@@ -5364,6 +5380,9 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                        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';
 
@@ -5763,6 +5782,7 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
        unsigned int cand;
        unsigned int num, i;
        int ignore_no_freqs = 0;
+       int unused_channels = wpas_p2p_num_unused_channels(wpa_s) > 0;
 
        os_memset(params, 0, sizeof(*params));
        params->role_go = 1;
@@ -5819,8 +5839,7 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
                        }
                }
 
-               if (!ignore_no_freqs &&
-                   wpas_p2p_num_unused_channels(wpa_s) <= 0) {
+               if (!ignore_no_freqs && !unused_channels) {
                        wpa_printf(MSG_DEBUG,
                                   "P2P: Cannot force GO on freq (%d MHz) as all the channels are in use",
                                   freq);
@@ -5835,12 +5854,13 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
        }
 
        /* consider using one of the shared frequencies */
-       if (num) {
+       if (num &&
+           (!wpa_s->conf->p2p_ignore_shared_freq || !unused_channels)) {
                cand = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
                if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
                        wpa_printf(MSG_DEBUG,
                                   "P2P: Use shared freq (%d MHz) for GO",
-                                  freq);
+                                  cand);
                        params->freq = cand;
                        goto success;
                }
@@ -5851,15 +5871,14 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
                                                       freqs[i].freq)) {
                                wpa_printf(MSG_DEBUG,
                                           "P2P: Use shared freq (%d MHz) for GO",
-                                          freq);
+                                          freqs[i].freq);
                                params->freq = freqs[i].freq;
                                goto success;
                        }
                }
        }
 
-       if (!ignore_no_freqs &&
-           wpas_p2p_num_unused_channels(wpa_s) <= 0) {
+       if (!ignore_no_freqs && !unused_channels) {
                wpa_printf(MSG_DEBUG,
                           "P2P: Cannot force GO on any of the channels we are already using");
                goto fail;
@@ -5985,7 +6004,7 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
                        "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;
        }
 
@@ -6099,8 +6118,10 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
        wpa_config_set_network_defaults(ssid);
        ssid->temporary = 1;
        ssid->proto = WPA_PROTO_RSN;
-       ssid->pairwise_cipher = WPA_CIPHER_CCMP;
-       ssid->group_cipher = WPA_CIPHER_CCMP;
+       ssid->pbss = params->pbss;
+       ssid->pairwise_cipher = params->pbss ? WPA_CIPHER_GCMP :
+               WPA_CIPHER_CCMP;
+       ssid->group_cipher = params->pbss ? WPA_CIPHER_GCMP : WPA_CIPHER_CCMP;
        ssid->key_mgmt = WPA_KEY_MGMT_PSK;
        ssid->ssid = os_malloc(params->ssid_len);
        if (ssid->ssid == NULL) {
@@ -6297,7 +6318,8 @@ struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *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));
@@ -6320,6 +6342,8 @@ struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
        cfg->cb_ctx = wpa_s;
        cfg->ie_update = wpas_p2p_ie_update;
        cfg->idle_update = wpas_p2p_idle_update;
+       cfg->ip_addr_alloc = WPA_GET_BE32(wpa_s->p2pdev->conf->ip_addr_start)
+               != 0;
 
        group = p2p_group_init(wpa_s->global->p2p, cfg);
        if (group == NULL)
@@ -6713,12 +6737,15 @@ void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
 
 void wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies)
 {
+       unsigned int bands;
+
        if (wpa_s->global->p2p_disabled)
                return;
        if (wpa_s->global->p2p == NULL)
                return;
 
-       p2p_scan_ie(wpa_s->global->p2p, ies, NULL);
+       bands = wpas_get_bands(wpa_s, NULL);
+       p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
 }
 
 
@@ -6911,7 +6938,6 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
 {
        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];
@@ -6970,11 +6996,10 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
                               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);
 }
 
 
@@ -8355,17 +8380,17 @@ static int wpas_p2p_nfc_auth_join(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
-       if (wpa_s->parent->p2p_oob_dev_pw_id !=
+       if (wpa_s->p2pdev->p2p_oob_dev_pw_id !=
            DEV_PW_NFC_CONNECTION_HANDOVER &&
-           !wpa_s->parent->p2p_oob_dev_pw) {
+           !wpa_s->p2pdev->p2p_oob_dev_pw) {
                wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known");
                return -1;
        }
        res = wpas_ap_wps_add_nfc_pw(
-               wpa_s, wpa_s->parent->p2p_oob_dev_pw_id,
-               wpa_s->parent->p2p_oob_dev_pw,
-               wpa_s->parent->p2p_peer_oob_pk_hash_known ?
-               wpa_s->parent->p2p_peer_oob_pubkey_hash : NULL);
+               wpa_s, wpa_s->p2pdev->p2p_oob_dev_pw_id,
+               wpa_s->p2pdev->p2p_oob_dev_pw,
+               wpa_s->p2pdev->p2p_peer_oob_pk_hash_known ?
+               wpa_s->p2pdev->p2p_peer_oob_pubkey_hash : NULL);
        if (res)
                return res;
 
@@ -8383,16 +8408,16 @@ static int wpas_p2p_nfc_auth_join(struct wpa_supplicant *wpa_s,
 
        wpa_s->global->p2p_invite_group = wpa_s;
        persistent = ssid->p2p_persistent_group &&
-               wpas_p2p_get_persistent(wpa_s->parent,
+               wpas_p2p_get_persistent(wpa_s->p2pdev,
                                        params->peer->p2p_device_addr,
                                        ssid->ssid, ssid->ssid_len);
-       wpa_s->parent->pending_invite_ssid_id = -1;
+       wpa_s->p2pdev->pending_invite_ssid_id = -1;
 
        return p2p_invite(wpa_s->global->p2p, params->peer->p2p_device_addr,
                          P2P_INVITE_ROLE_ACTIVE_GO, wpa_s->own_addr,
                          ssid->ssid, ssid->ssid_len, ssid->frequency,
                          wpa_s->global->p2p_dev_addr, persistent, 0,
-                         wpa_s->parent->p2p_oob_dev_pw_id);
+                         wpa_s->p2pdev->p2p_oob_dev_pw_id);
 }