+
+ *tdls_supported = 0;
+ *tdls_ext_setup = 0;
+ *tdls_chan_switch = 0;
+
+ if (!wpa_s->drv_capa_known)
+ return -1;
+
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)
+ *tdls_supported = 1;
+
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP)
+ *tdls_ext_setup = 1;
+
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH)
+ *tdls_chan_switch = 1;
+
+ return 0;
+}
+
+
+static int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst,
+ u8 action_code, u8 dialog_token,
+ u16 status_code, u32 peer_capab,
+ int initiator, const u8 *buf,
+ size_t len)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code, dialog_token,
+ status_code, peer_capab, initiator, buf,
+ len);
+}
+
+
+static int wpa_supplicant_tdls_oper(void *ctx, int oper, const u8 *peer)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ return wpa_drv_tdls_oper(wpa_s, oper, peer);
+}
+
+
+static int wpa_supplicant_tdls_peer_addset(
+ void *ctx, const u8 *peer, int add, u16 aid, u16 capability,
+ const u8 *supp_rates, size_t supp_rates_len,
+ const struct ieee80211_ht_capabilities *ht_capab,
+ const struct ieee80211_vht_capabilities *vht_capab,
+ u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len,
+ const u8 *supp_channels, size_t supp_channels_len,
+ const u8 *supp_oper_classes, size_t supp_oper_classes_len)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ struct hostapd_sta_add_params params;
+
+ os_memset(¶ms, 0, sizeof(params));
+
+ params.addr = peer;
+ params.aid = aid;
+ params.capability = capability;
+ params.flags = WPA_STA_TDLS_PEER | WPA_STA_AUTHORIZED;
+
+ /*
+ * Don't rely only on qosinfo for WMM capability. It may be 0 even when
+ * present. Allow the WMM IE to also indicate QoS support.
+ */
+ if (wmm || qosinfo)
+ params.flags |= WPA_STA_WMM;
+
+ params.ht_capabilities = ht_capab;
+ params.vht_capabilities = vht_capab;
+ params.qosinfo = qosinfo;
+ params.listen_interval = 0;
+ params.supp_rates = supp_rates;
+ params.supp_rates_len = supp_rates_len;
+ params.set = !add;
+ params.ext_capab = ext_capab;
+ params.ext_capab_len = ext_capab_len;
+ params.supp_channels = supp_channels;
+ params.supp_channels_len = supp_channels_len;
+ params.supp_oper_classes = supp_oper_classes;
+ params.supp_oper_classes_len = supp_oper_classes_len;
+
+ return wpa_drv_sta_add(wpa_s, ¶ms);
+}
+
+
+static int wpa_supplicant_tdls_enable_channel_switch(
+ void *ctx, const u8 *addr, u8 oper_class,
+ const struct hostapd_freq_params *params)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ return wpa_drv_tdls_enable_channel_switch(wpa_s, addr, oper_class,
+ params);
+}
+
+
+static int wpa_supplicant_tdls_disable_channel_switch(void *ctx, const u8 *addr)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ return wpa_drv_tdls_disable_channel_switch(wpa_s, addr);
+}
+
+#endif /* CONFIG_TDLS */
+
+#endif /* CONFIG_NO_WPA */
+
+
+enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field)
+{
+ if (os_strcmp(field, "IDENTITY") == 0)
+ return WPA_CTRL_REQ_EAP_IDENTITY;
+ else if (os_strcmp(field, "PASSWORD") == 0)
+ return WPA_CTRL_REQ_EAP_PASSWORD;
+ else if (os_strcmp(field, "NEW_PASSWORD") == 0)
+ return WPA_CTRL_REQ_EAP_NEW_PASSWORD;
+ else if (os_strcmp(field, "PIN") == 0)
+ return WPA_CTRL_REQ_EAP_PIN;
+ else if (os_strcmp(field, "OTP") == 0)
+ return WPA_CTRL_REQ_EAP_OTP;
+ else if (os_strcmp(field, "PASSPHRASE") == 0)
+ return WPA_CTRL_REQ_EAP_PASSPHRASE;
+ else if (os_strcmp(field, "SIM") == 0)
+ return WPA_CTRL_REQ_SIM;
+ else if (os_strcmp(field, "PSK_PASSPHRASE") == 0)
+ return WPA_CTRL_REQ_PSK_PASSPHRASE;
+ else if (os_strcmp(field, "EXT_CERT_CHECK") == 0)
+ return WPA_CTRL_REQ_EXT_CERT_CHECK;
+ return WPA_CTRL_REQ_UNKNOWN;
+}
+
+
+const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
+ const char *default_txt,
+ const char **txt)
+{
+ const char *ret = NULL;
+
+ *txt = default_txt;
+
+ switch (field) {
+ case WPA_CTRL_REQ_EAP_IDENTITY:
+ *txt = "Identity";
+ ret = "IDENTITY";
+ break;
+ case WPA_CTRL_REQ_EAP_PASSWORD:
+ *txt = "Password";
+ ret = "PASSWORD";
+ break;
+ case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
+ *txt = "New Password";
+ ret = "NEW_PASSWORD";
+ break;
+ case WPA_CTRL_REQ_EAP_PIN:
+ *txt = "PIN";
+ ret = "PIN";
+ break;
+ case WPA_CTRL_REQ_EAP_OTP:
+ ret = "OTP";
+ break;
+ case WPA_CTRL_REQ_EAP_PASSPHRASE:
+ *txt = "Private key passphrase";
+ ret = "PASSPHRASE";
+ break;
+ case WPA_CTRL_REQ_SIM:
+ ret = "SIM";
+ break;
+ case WPA_CTRL_REQ_PSK_PASSPHRASE:
+ *txt = "PSK or passphrase";
+ ret = "PSK_PASSPHRASE";
+ break;
+ case WPA_CTRL_REQ_EXT_CERT_CHECK:
+ *txt = "External server certificate validation";
+ ret = "EXT_CERT_CHECK";
+ break;
+ default:
+ break;
+ }
+
+ /* txt needs to be something */
+ if (*txt == NULL) {
+ wpa_printf(MSG_WARNING, "No message for request %d", field);
+ ret = NULL;
+ }
+
+ return ret;
+}
+
+
+void wpas_send_ctrl_req(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ const char *field_name, const char *txt)
+{