}
+void p2p_set_go_role(struct p2p_data *p2p, bool val)
+{
+ p2p->go_role = val;
+}
+
+
void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer)
{
struct p2p_go_neg_results res;
}
#endif /* CONFIG_PASN */
- p2p_set_state(p2p, P2P_PROVISIONING);
- p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
+ if (p2p->go_role && peer->p2p2) {
+ p2p->cfg->set_go_security_config(p2p->cfg->cb_ctx, &res);
+ p2p->go_role = false;
+ } else {
+ p2p_set_state(p2p, P2P_PROVISIONING);
+ p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
+ }
+
forced_memzero(&res, sizeof(res));
}
*/
void (*go_neg_completed)(void *ctx, struct p2p_go_neg_results *res);
+ /**
+ * set_go_security_config - Set security configuration for P2P GO
+ * @ctx: Callback context from cb_ctx
+ * @res: GO Negotiation results
+ *
+ * This callback is used to set PMK/passphrase derived during PASN
+ * authentication with a P2P client. This will fetch an active P2P group
+ * owner instance and configure PMKSA in case of password based PASN, or
+ * configures the passphrase and derive PT in case of unauthenticated
+ * PASN.
+ */
+ void (*set_go_security_config)(void *ctx,
+ struct p2p_go_neg_results *res);
+
/**
* sd_request - Callback on Service Discovery Request
* @ctx: Callback context from cb_ctx
*/
int p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params);
+/**
+ * p2p_set_go_role - Set the current role of P2P device
+ * @p2p: P2P module context from p2p_init()
+ * @val: 1 if P2P GO, 0 to reset the role variable
+ *
+ * This role is configured as P2P GO when authorizing a P2P Client to join the
+ * group. Once PASN authentication with GO negotiation with predefined GO intent
+ * values (15 for P2P GO) is completed, the role helps to configure PMK derived
+ * during the PASN authentication.
+ */
+void p2p_set_go_role(struct p2p_data *p2p, bool val);
+
/**
* p2p_get_group_capab - Get Group Capability from P2P IE data
* @p2p_ie: P2P IE(s) contents
* conclusion of a successful pairing. */
char dev_sae_password[100];
char peer_sae_password[100];
+
+ /* Variable used to know the role of the device in a given instance.
+ * go_role variable is set while authorizing a P2P Client for PASN
+ * authentication with predefined GO intent value for GO (15 for
+ * P2P-GO). Once the authentication is completed and security
+ * configuration is done, this variable is reset to false.
+ */
+ bool go_role;
};
/**
}
+static void wpas_set_go_security_config(void *ctx,
+ struct p2p_go_neg_results *params)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ struct wpa_supplicant *tmp, *ifs = NULL;
+ struct hostapd_data *hapd;
+
+ if (!params->p2p2)
+ return;
+
+ dl_list_for_each(tmp, &wpa_s->radio->ifaces, struct wpa_supplicant,
+ radio_list) {
+ struct wpa_ssid *ssid = tmp->current_ssid;
+
+ if (ssid && ssid->mode == WPAS_MODE_P2P_GO &&
+ ssid->ssid && ssid->ssid_len == params->ssid_len &&
+ os_memcmp(ssid->ssid, params->ssid, params->ssid_len) == 0)
+ {
+ ifs = tmp;
+ break;
+ }
+ }
+
+ if (!ifs || !ifs->ap_iface)
+ return;
+
+ hapd = ifs->ap_iface->bss[0];
+ hapd->conf->wps_state = 0;
+
+ if (params->akmp == WPA_KEY_MGMT_SAE) {
+ wpa_printf(MSG_DEBUG, "P2P: Adding PMK for peer: " MACSTR,
+ MAC2STR(params->peer_device_addr));
+ wpa_auth_pmksa_add_sae(hapd->wpa_auth,
+ params->peer_device_addr,
+ params->pmk, params->pmk_len,
+ params->pmkid, WPA_KEY_MGMT_SAE);
+ }
+}
+
+
static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
{
struct wpa_supplicant *wpa_s = ctx;
p2p.send_action = wpas_send_action;
p2p.send_action_done = wpas_send_action_done;
p2p.go_neg_completed = wpas_go_neg_completed;
+ p2p.set_go_security_config = wpas_set_go_security_config;
p2p.go_neg_req_rx = wpas_go_neg_req_rx;
p2p.dev_found = wpas_dev_found;
p2p.dev_lost = wpas_dev_lost;
os_free(wpa_s->global->add_psk);
wpa_s->global->add_psk = NULL;
+ p2p_set_go_role(wpa_s->global->p2p, false);
wpa_s->global->p2p_fail_on_wps_complete = 0;
wpa_s->global->pending_p2ps_group = 0;
wpa_s->global->pending_p2ps_group_freq = 0;