diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 93b740eba..d4b3af362 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -352,6 +352,46 @@ static int hostapd_ctrl_iface_wps_nfc_token(struct hostapd_data *hapd, return -1; } + + +static int hostapd_ctrl_iface_nfc_get_handover_sel(struct hostapd_data *hapd, + char *cmd, char *reply, + size_t max_len) +{ + struct wpabuf *buf; + int res; + char *pos; + int ndef; + + pos = os_strchr(cmd, ' '); + if (pos == NULL) + return -1; + *pos++ = '\0'; + + if (os_strcmp(cmd, "WPS") == 0) + ndef = 0; + else if (os_strcmp(cmd, "NDEF") == 0) + ndef = 1; + else + return -1; + + if (os_strcmp(pos, "WPS-CR") == 0) + buf = hostapd_wps_nfc_hs_cr(hapd, ndef); + else + buf = NULL; + if (buf == NULL) + return -1; + + res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), + wpabuf_len(buf)); + reply[res++] = '\n'; + reply[res] = '\0'; + + wpabuf_free(buf); + + return res; +} + #endif /* CONFIG_WPS_NFC */ @@ -913,6 +953,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx, } else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) { reply_len = hostapd_ctrl_iface_wps_nfc_token( hapd, buf + 14, reply, reply_size); + } else if (os_strncmp(buf, "NFC_GET_HANDOVER_SEL ", 21) == 0) { + reply_len = hostapd_ctrl_iface_nfc_get_handover_sel( + hapd, buf + 21, reply, reply_size); #endif /* CONFIG_WPS_NFC */ #endif /* CONFIG_WPS */ #ifdef CONFIG_WNM diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c index 0e840eaf7..a8a8dfb68 100644 --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c @@ -470,6 +470,29 @@ static int hostapd_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, } return wpa_ctrl_command(ctrl, cmd); } + + +static int hostapd_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, + int argc, char *argv[]) +{ + char cmd[64]; + int res; + + if (argc != 2) { + printf("Invalid 'nfc_get_handover_sel' command - two arguments " + "are required.\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "NFC_GET_HANDOVER_SEL %s %s", + argv[0], argv[1]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long NFC_GET_HANDOVER_SEL command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} + #endif /* CONFIG_WPS_NFC */ @@ -791,6 +814,7 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = { { "wps_nfc_tag_read", hostapd_cli_cmd_wps_nfc_tag_read }, { "wps_nfc_config_token", hostapd_cli_cmd_wps_nfc_config_token }, { "wps_nfc_token", hostapd_cli_cmd_wps_nfc_token }, + { "nfc_get_handover_sel", hostapd_cli_cmd_nfc_get_handover_sel }, #endif /* CONFIG_WPS_NFC */ { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin }, { "wps_config", hostapd_cli_cmd_wps_config }, diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c index 5ce4f1be3..c9f628932 100644 --- a/src/ap/wps_hostapd.c +++ b/src/ap/wps_hostapd.c @@ -1583,6 +1583,16 @@ struct wpabuf * hostapd_wps_nfc_config_token(struct hostapd_data *hapd, } +struct wpabuf * hostapd_wps_nfc_hs_cr(struct hostapd_data *hapd, int ndef) +{ + /* + * Handover Select carrier record for WPS uses the same format as + * configuration token. + */ + return hostapd_wps_nfc_config_token(hapd, ndef); +} + + struct wpabuf * hostapd_wps_nfc_token_gen(struct hostapd_data *hapd, int ndef) { return wps_nfc_token_gen(ndef, &hapd->conf->wps_nfc_dev_pw_id, diff --git a/src/ap/wps_hostapd.h b/src/ap/wps_hostapd.h index 4e5026b45..a2c2cf021 100644 --- a/src/ap/wps_hostapd.h +++ b/src/ap/wps_hostapd.h @@ -35,6 +35,7 @@ int hostapd_wps_nfc_tag_read(struct hostapd_data *hapd, const struct wpabuf *data); struct wpabuf * hostapd_wps_nfc_config_token(struct hostapd_data *hapd, int ndef); +struct wpabuf * hostapd_wps_nfc_hs_cr(struct hostapd_data *hapd, int ndef); struct wpabuf * hostapd_wps_nfc_token_gen(struct hostapd_data *hapd, int ndef); int hostapd_wps_nfc_token_enable(struct hostapd_data *hapd); void hostapd_wps_nfc_token_disable(struct hostapd_data *hapd);