aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorArif Hussain <c_arifh@qca.qualcomm.com>2014-01-24 14:14:29 (GMT)
committerJouni Malinen <j@w1.fi>2014-01-27 09:49:05 (GMT)
commit253f2e37957e726677d545f5598aad56d7d33bf5 (patch)
tree08b770d19c906a85220aefd1cf224804e2f537b1 /wpa_supplicant
parent1682c6236017f28b8fdb3b791565c835e988a559 (diff)
downloadhostap-253f2e37957e726677d545f5598aad56d7d33bf5.zip
hostap-253f2e37957e726677d545f5598aad56d7d33bf5.tar.gz
hostap-253f2e37957e726677d545f5598aad56d7d33bf5.tar.bz2
P2P: Apply unsafe frequency rules to available channels
This adds a QCA vendor specific nl80211 event to allow the driver to indicate a list of frequency ranges that should be avoided due to interference or possible known co-existance constraints. Such frequencies are marked as not allowed for P2P use to force groups to be formed on different channels. If a P2P GO is operating on a channel that the driver recommended not to use, a notification about this is sent on the control interface and upper layer code may decide to tear down the group and optionally restart it on another channel. As a TODO item, this could also be changed to use CSA to avoid removing the group. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/events.c55
-rw-r--r--wpa_supplicant/p2p_supplicant.c2
-rw-r--r--wpa_supplicant/wpa_supplicant.c1
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h1
4 files changed, 59 insertions, 0 deletions
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index d9449fd..d5ac6bf 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2775,6 +2775,58 @@ static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
}
+static void wpa_supplicant_notify_avoid_freq(struct wpa_supplicant *wpa_s,
+ union wpa_event_data *event)
+{
+#ifdef CONFIG_P2P
+ struct wpa_supplicant *ifs;
+#endif /* CONFIG_P2P */
+ struct wpa_freq_range_list *list;
+ char *str = NULL;
+
+ list = &event->freq_range;
+
+ if (list->num)
+ str = freq_range_list_str(list);
+ wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AVOID_FREQ "ranges=%s",
+ str ? str : "");
+
+#ifdef CONFIG_P2P
+ if (freq_range_list_parse(&wpa_s->global->p2p_go_avoid_freq, str)) {
+ wpa_dbg(wpa_s, MSG_ERROR, "%s: Failed to parse freq range",
+ __func__);
+ } else {
+ wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Update channel list based on frequency avoid event");
+ wpas_p2p_update_channel_list(wpa_s);
+ }
+
+ for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
+ int freq;
+ if (!ifs->current_ssid ||
+ !ifs->current_ssid->p2p_group ||
+ (ifs->current_ssid->mode != WPAS_MODE_P2P_GO &&
+ ifs->current_ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION))
+ continue;
+
+ freq = ifs->current_ssid->frequency;
+ if (!freq_range_list_includes(list, freq)) {
+ wpa_dbg(ifs, MSG_DEBUG, "P2P GO operating frequency %d MHz in safe range",
+ freq);
+ continue;
+ }
+
+ wpa_dbg(ifs, MSG_DEBUG, "P2P GO operating in unsafe frequency %d MHz",
+ freq);
+ /* TODO: Consider using CSA or removing the group within
+ * wpa_supplicant */
+ wpa_msg(ifs, MSG_INFO, P2P_EVENT_REMOVE_AND_REFORM_GROUP);
+ }
+#endif /* CONFIG_P2P */
+
+ os_free(str);
+}
+
+
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
union wpa_event_data *data)
{
@@ -3266,6 +3318,9 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
wpas_wps_start_pbc(wpa_s, NULL, 0);
#endif /* CONFIG_WPS */
break;
+ case EVENT_AVOID_FREQUENCIES:
+ wpa_supplicant_notify_avoid_freq(wpa_s, data);
+ break;
case EVENT_CONNECT_FAILED_REASON:
#ifdef CONFIG_AP
if (!wpa_s->ap_iface || !data)
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 889a949..a7eb9aa 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -3190,6 +3190,8 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
static int wpas_p2p_disallowed_freq(struct wpa_global *global,
unsigned int freq)
{
+ if (freq_range_list_includes(&global->p2p_go_avoid_freq, freq))
+ return 1;
return freq_range_list_includes(&global->p2p_disallow_freq, freq);
}
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index aa9c32d..1bb1a2c 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3927,6 +3927,7 @@ void wpa_supplicant_deinit(struct wpa_global *global)
os_free(global->params.override_ctrl_interface);
os_free(global->p2p_disallow_freq.range);
+ os_free(global->p2p_go_avoid_freq.range);
os_free(global->add_psk);
os_free(global);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 078856e..68995fc 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -252,6 +252,7 @@ struct wpa_global {
int p2p_disabled;
int cross_connection;
struct wpa_freq_range_list p2p_disallow_freq;
+ struct wpa_freq_range_list p2p_go_avoid_freq;
enum wpa_conc_pref {
WPA_CONC_PREF_NOT_SET,
WPA_CONC_PREF_STA,