}
+#ifdef CONFIG_TESTING_OPTIONS
+static int wpas_ctrl_iface_set_dso(struct wpa_supplicant *wpa_s,
+ const char *val)
+{
+ u8 bssid[ETH_ALEN];
+ const char *pos = val;
+ struct driver_signal_override *dso = NULL, *tmp, parsed;
+
+ if (hwaddr_aton(pos, bssid))
+ return -1;
+ pos = os_strchr(pos, ' ');
+
+ dl_list_for_each(tmp, &wpa_s->drv_signal_override,
+ struct driver_signal_override, list) {
+ if (os_memcmp(bssid, tmp->bssid, ETH_ALEN) == 0) {
+ dso = tmp;
+ break;
+ }
+ }
+
+ if (!pos) {
+ /* Remove existing entry */
+ if (dso) {
+ dl_list_del(&dso->list);
+ os_free(dso);
+ }
+ return 0;
+ }
+ pos++;
+
+ /* Update an existing entry or add a new one */
+ os_memset(&parsed, 0, sizeof(parsed));
+ if (sscanf(pos, "%d %d %d %d %d",
+ &parsed.si_current_signal,
+ &parsed.si_avg_signal,
+ &parsed.si_avg_beacon_signal,
+ &parsed.si_current_noise,
+ &parsed.scan_level) != 5)
+ return -1;
+
+ if (!dso) {
+ dso = os_zalloc(sizeof(*dso));
+ if (!dso)
+ return -1;
+ os_memcpy(dso->bssid, bssid, ETH_ALEN);
+ dl_list_add(&wpa_s->drv_signal_override, &dso->list);
+ }
+ dso->si_current_signal = parsed.si_current_signal;
+ dso->si_avg_signal = parsed.si_avg_signal;
+ dso->si_avg_beacon_signal = parsed.si_avg_beacon_signal;
+ dso->si_current_noise = parsed.si_current_noise;
+ dso->scan_level = parsed.scan_level;
+
+ return 0;
+}
+#endif /* CONFIG_TESTING_OPTIONS */
+
+
static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
char *cmd)
{
wpa_s->sae_commit_override = NULL;
else
wpa_s->sae_commit_override = wpabuf_parse_bin(value);
+ } else if (os_strcasecmp(cmd, "driver_signal_override") == 0) {
+ ret = wpas_ctrl_iface_set_dso(wpa_s, value);
#ifdef CONFIG_DPP
} else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
os_free(wpa_s->dpp_config_obj_override);
wpa_s->rsnxe_override_assoc = NULL;
wpabuf_free(wpa_s->rsnxe_override_eapol);
wpa_s->rsnxe_override_eapol = NULL;
+ wpas_clear_driver_signal_override(wpa_s);
#ifdef CONFIG_DPP
os_free(wpa_s->dpp_config_obj_override);
wpa_s->dpp_config_obj_override = NULL;
return -1;
}
-static inline struct wpa_scan_results * wpa_drv_get_scan_results2(
- struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->get_scan_results2)
- return wpa_s->driver->get_scan_results2(wpa_s->drv_priv);
- return NULL;
-}
+struct wpa_scan_results *
+wpa_drv_get_scan_results2(struct wpa_supplicant *wpa_s);
static inline int wpa_drv_get_bssid(struct wpa_supplicant *wpa_s, u8 *bssid)
{
return -1;
}
-static inline int wpa_drv_signal_poll(struct wpa_supplicant *wpa_s,
- struct wpa_signal_info *si)
-{
- if (wpa_s->driver->signal_poll)
- return wpa_s->driver->signal_poll(wpa_s->drv_priv, si);
- return -1;
-}
+int wpa_drv_signal_poll(struct wpa_supplicant *wpa_s,
+ struct wpa_signal_info *si);
static inline int wpa_drv_channel_info(struct wpa_supplicant *wpa_s,
struct wpa_channel_info *ci)
}
+#ifdef CONFIG_TESTING_OPTIONS
+void wpas_clear_driver_signal_override(struct wpa_supplicant *wpa_s)
+{
+ struct driver_signal_override *dso;
+
+ while ((dso = dl_list_first(&wpa_s->drv_signal_override,
+ struct driver_signal_override, list))) {
+ dl_list_del(&dso->list);
+ os_free(dso);
+ }
+}
+#endif /* CONFIG_TESTING_OPTIONS */
+
+
static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
{
int i;
wpa_s->rsnxe_override_assoc = NULL;
wpabuf_free(wpa_s->rsnxe_override_eapol);
wpa_s->rsnxe_override_eapol = NULL;
+ wpas_clear_driver_signal_override(wpa_s);
#endif /* CONFIG_TESTING_OPTIONS */
if (wpa_s->conf != NULL) {
dl_list_init(&wpa_s->bss_tmp_disallowed);
dl_list_init(&wpa_s->fils_hlp_req);
+#ifdef CONFIG_TESTING_OPTIONS
+ dl_list_init(&wpa_s->drv_signal_override);
+#endif /* CONFIG_TESTING_OPTIONS */
return wpa_s;
}
return 0;
}
+
+
+int wpa_drv_signal_poll(struct wpa_supplicant *wpa_s,
+ struct wpa_signal_info *si)
+{
+ int res;
+
+ if (!wpa_s->driver->signal_poll)
+ return -1;
+
+ res = wpa_s->driver->signal_poll(wpa_s->drv_priv, si);
+
+#ifdef CONFIG_TESTING_OPTIONS
+ if (res == 0) {
+ struct driver_signal_override *dso;
+
+ dl_list_for_each(dso, &wpa_s->drv_signal_override,
+ struct driver_signal_override, list) {
+ if (os_memcmp(wpa_s->bssid, dso->bssid,
+ ETH_ALEN) != 0)
+ continue;
+ wpa_printf(MSG_DEBUG,
+ "Override driver signal_poll information: current_signal: %d->%d avg_signal: %d->%d avg_beacon_signal: %d->%d current_noise: %d->%d",
+ si->current_signal,
+ dso->si_current_signal,
+ si->avg_signal,
+ dso->si_avg_signal,
+ si->avg_beacon_signal,
+ dso->si_avg_beacon_signal,
+ si->current_noise,
+ dso->si_current_noise);
+ si->current_signal = dso->si_current_signal;
+ si->avg_signal = dso->si_avg_signal;
+ si->avg_beacon_signal = dso->si_avg_beacon_signal;
+ si->current_noise = dso->si_current_noise;
+ break;
+ }
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+
+ return res;
+}
+
+
+struct wpa_scan_results *
+wpa_drv_get_scan_results2(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_scan_results *scan_res;
+#ifdef CONFIG_TESTING_OPTIONS
+ size_t idx;
+#endif /* CONFIG_TESTING_OPTIONS */
+
+ if (!wpa_s->driver->get_scan_results2)
+ return NULL;
+
+ scan_res = wpa_s->driver->get_scan_results2(wpa_s->drv_priv);
+
+#ifdef CONFIG_TESTING_OPTIONS
+ for (idx = 0; scan_res && idx < scan_res->num; idx++) {
+ struct driver_signal_override *dso;
+ struct wpa_scan_res *res = scan_res->res[idx];
+
+ dl_list_for_each(dso, &wpa_s->drv_signal_override,
+ struct driver_signal_override, list) {
+ if (os_memcmp(res->bssid, dso->bssid, ETH_ALEN) != 0)
+ continue;
+ wpa_printf(MSG_DEBUG,
+ "Override driver scan signal level %d->%d for "
+ MACSTR,
+ res->level, dso->scan_level,
+ MAC2STR(res->bssid));
+ res->flags |= WPA_SCAN_QUAL_INVALID;
+ if (dso->scan_level < 0)
+ res->flags |= WPA_SCAN_LEVEL_DBM;
+ else
+ res->flags &= ~WPA_SCAN_LEVEL_DBM;
+ res->level = dso->scan_level;
+ break;
+ }
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+
+ return scan_res;
+}
struct wpabuf *pkt;
};
+struct driver_signal_override {
+ struct dl_list list;
+ u8 bssid[ETH_ALEN];
+ int si_current_signal;
+ int si_avg_signal;
+ int si_avg_beacon_signal;
+ int si_current_noise;
+ int scan_level;
+};
+
/**
* struct wpa_supplicant - Internal data for wpa_supplicant interface
*
int *extra_sae_rejected_groups;
struct wpabuf *rsnxe_override_assoc;
struct wpabuf *rsnxe_override_eapol;
+ struct dl_list drv_signal_override;
#endif /* CONFIG_TESTING_OPTIONS */
struct wmm_ac_assoc_data *wmm_ac_assoc_info;
int wpa_is_fils_supported(struct wpa_supplicant *wpa_s);
int wpa_is_fils_sk_pfs_supported(struct wpa_supplicant *wpa_s);
+void wpas_clear_driver_signal_override(struct wpa_supplicant *wpa_s);
+
#endif /* WPA_SUPPLICANT_I_H */