int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
const u8 *pin, size_t pin_len,
const struct wps_credential *cred);
+struct wpabuf * wps_er_config_token_from_cred(struct wps_context *wps,
+ struct wps_credential *cred);
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
const u8 *addr);
#ifdef CONFIG_WPS_NFC
-struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
- const u8 *addr)
+
+struct wpabuf * wps_er_config_token_from_cred(struct wps_context *wps,
+ struct wps_credential *cred)
{
- struct wps_er_ap *ap;
struct wpabuf *ret;
struct wps_data data;
- if (er == NULL)
- return NULL;
-
- ap = wps_er_ap_get(er, NULL, uuid, addr);
- if (ap == NULL)
- return NULL;
- if (ap->ap_settings == NULL) {
- wpa_printf(MSG_DEBUG, "WPS ER: No settings known for the "
- "selected AP");
- return NULL;
- }
-
ret = wpabuf_alloc(500);
if (ret == NULL)
return NULL;
os_memset(&data, 0, sizeof(data));
- data.wps = er->wps;
- data.use_cred = ap->ap_settings;
+ data.wps = wps;
+ data.use_cred = cred;
if (wps_build_version(ret) ||
wps_build_cred(&data, ret) ||
wps_build_wfa_ext(ret, 0, NULL, 0)) {
return ret;
}
+
+
+struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
+ const u8 *addr)
+{
+ struct wps_er_ap *ap;
+
+ if (er == NULL)
+ return NULL;
+
+ ap = wps_er_ap_get(er, NULL, uuid, addr);
+ if (ap == NULL)
+ return NULL;
+ if (ap->ap_settings == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS ER: No settings known for the "
+ "selected AP");
+ return NULL;
+ }
+
+ return wps_er_config_token_from_cred(er->wps, ap->ap_settings);
+}
+
#endif /* CONFIG_WPS_NFC */
can be used to touch an NFC interface on a station to provision the
credentials needed to access the network.
+The "wps_nfc_config_token <WPS/NDEF> <network id>" command can be used
+to build an NFC configuration token based on a locally configured
+network.
+
If the station includes NFC interface and reads an NFC tag with a MIME
media type "application/vnd.wfa.wsc", the NDEF message payload (with or
without NDEF encapsulation) can be delivered to wpa_supplicant using the
int ndef;
struct wpabuf *buf;
int res;
+ char *pos;
+ pos = os_strchr(cmd, ' ');
+ if (pos)
+ *pos++ = '\0';
if (os_strcmp(cmd, "WPS") == 0)
ndef = 0;
else if (os_strcmp(cmd, "NDEF") == 0)
else
return -1;
- buf = wpas_wps_nfc_config_token(wpa_s, ndef);
+ buf = wpas_wps_nfc_config_token(wpa_s, ndef, pos);
if (buf == NULL)
return -1;
print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
-def wpas_get_config_token():
+def wpas_get_config_token(id=None):
wpas = wpas_connect()
if (wpas == None):
return None
+ if id:
+ return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF " + id).rstrip().decode("hex")
return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
time.sleep(0.1)
-def wps_write_config_tag(clf):
+def wps_write_config_tag(clf, id=None):
print "Write WPS config token"
- data = wpas_get_config_token()
+ data = wpas_get_config_token(id)
if (data == None):
print "Could not get WPS config token from wpa_supplicant"
return
wps_write_config_tag(clf)
raise SystemExit
+ if len(sys.argv) > 2 and sys.argv[1] == "write-config-id":
+ wps_write_config_tag(clf, sys.argv[2])
+ raise SystemExit
+
if len(sys.argv) > 2 and sys.argv[1] == "write-er-config":
wps_write_er_config_tag(clf, sys.argv[2])
raise SystemExit
}
+static int wpas_wps_network_to_cred(struct wpa_ssid *ssid,
+ struct wps_credential *cred)
+{
+ os_memset(cred, 0, sizeof(*cred));
+ if (ssid->ssid_len > 32)
+ return -1;
+ os_memcpy(cred->ssid, ssid->ssid, ssid->ssid_len);
+ cred->ssid_len = ssid->ssid_len;
+ if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
+ cred->auth_type = (ssid->proto & WPA_PROTO_RSN) ?
+ WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
+ if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
+ cred->encr_type = WPS_ENCR_AES;
+ else
+ cred->encr_type = WPS_ENCR_TKIP;
+ if (ssid->passphrase) {
+ cred->key_len = os_strlen(ssid->passphrase);
+ if (cred->key_len >= 64)
+ return -1;
+ os_memcpy(cred->key, ssid->passphrase, cred->key_len);
+ } else if (ssid->psk_set) {
+ cred->key_len = 32;
+ os_memcpy(cred->key, ssid->psk, 32);
+ } else
+ return -1;
+ } else {
+ cred->auth_type = WPS_AUTH_OPEN;
+ cred->encr_type = WPS_ENCR_NONE;
+ }
+
+ return 0;
+}
+
+
int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
int id)
{
if (ssid == NULL || ssid->ssid == NULL)
return -1;
- os_memset(&cred, 0, sizeof(cred));
- if (ssid->ssid_len > 32)
+ if (wpas_wps_network_to_cred(ssid, &cred) < 0)
return -1;
- os_memcpy(cred.ssid, ssid->ssid, ssid->ssid_len);
- cred.ssid_len = ssid->ssid_len;
- if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
- cred.auth_type = (ssid->proto & WPA_PROTO_RSN) ?
- WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
- if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
- cred.encr_type = WPS_ENCR_AES;
- else
- cred.encr_type = WPS_ENCR_TKIP;
- if (ssid->passphrase) {
- cred.key_len = os_strlen(ssid->passphrase);
- if (cred.key_len >= 64)
- return -1;
- os_memcpy(cred.key, ssid->passphrase, cred.key_len);
- } else if (ssid->psk_set) {
- cred.key_len = 32;
- os_memcpy(cred.key, ssid->psk, 32);
- } else
- return -1;
- } else {
- cred.auth_type = WPS_AUTH_OPEN;
- cred.encr_type = WPS_ENCR_NONE;
- }
return wps_er_set_config(wpa_s->wps_er, use_uuid, use_addr, &cred);
}
#ifdef CONFIG_WPS_NFC
+#ifdef CONFIG_WPS_ER
+static struct wpabuf *
+wpas_wps_network_config_token(struct wpa_supplicant *wpa_s, int ndef,
+ struct wpa_ssid *ssid)
+{
+ struct wpabuf *ret;
+ struct wps_credential cred;
+
+ if (wpas_wps_network_to_cred(ssid, &cred) < 0)
+ return NULL;
+
+ ret = wps_er_config_token_from_cred(wpa_s->wps, &cred);
+
+ if (ndef && ret) {
+ struct wpabuf *tmp;
+ tmp = ndef_build_wifi(ret);
+ wpabuf_free(ret);
+ if (tmp == NULL)
+ return NULL;
+ ret = tmp;
+ }
+
+ return ret;
+}
+#endif /* CONFIG_WPS_ER */
+
+
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
- int ndef)
+ int ndef, const char *id_str)
{
+#ifdef CONFIG_WPS_ER
+ if (id_str) {
+ int id;
+ char *end = NULL;
+ struct wpa_ssid *ssid;
+
+ id = strtol(id_str, &end, 10);
+ if (end && *end)
+ return NULL;
+
+ ssid = wpa_config_get_network(wpa_s->conf, id);
+ if (ssid == NULL)
+ return NULL;
+ return wpas_wps_network_config_token(wpa_s, ndef, ssid);
+ }
+#endif /* CONFIG_WPS_ER */
#ifdef CONFIG_AP
if (wpa_s->ap_iface)
return wpas_ap_wps_nfc_config_token(wpa_s, ndef);
int wpas_wps_in_progress(struct wpa_supplicant *wpa_s);
void wpas_wps_update_config(struct wpa_supplicant *wpa_s);
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
- int ndef);
+ int ndef, const char *id_str);
struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef);
int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid);
int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,