Root/package/hostapd/patches/750-dynamic_20_40_mhz.patch

1--- a/hostapd/config_file.c
2+++ b/hostapd/config_file.c
3@@ -1935,6 +1935,10 @@ struct hostapd_config * hostapd_config_r
4                        "ht_capab", line);
5                 errors++;
6             }
7+ } else if (os_strcmp(buf, "dynamic_ht40") == 0) {
8+ conf->dynamic_ht40 = atoi(pos);
9+ if (conf->dynamic_ht40 == 1)
10+ conf->dynamic_ht40 = 1500;
11         } else if (os_strcmp(buf, "require_ht") == 0) {
12             conf->require_ht = atoi(pos);
13 #endif /* CONFIG_IEEE80211N */
14--- a/src/ap/ap_config.h
15+++ b/src/ap/ap_config.h
16@@ -416,6 +416,7 @@ struct hostapd_config {
17     int ieee80211n;
18     int secondary_channel;
19     int require_ht;
20+ int dynamic_ht40;
21 };
22 
23 
24--- a/src/ap/hostapd.c
25+++ b/src/ap/hostapd.c
26@@ -27,6 +27,7 @@
27 #include "beacon.h"
28 #include "iapp.h"
29 #include "ieee802_1x.h"
30+#include "ieee802_11.h"
31 #include "ieee802_11_auth.h"
32 #include "vlan_init.h"
33 #include "wpa_auth.h"
34@@ -291,6 +292,7 @@ static void hostapd_cleanup_iface_pre(st
35  */
36 static void hostapd_cleanup_iface(struct hostapd_iface *iface)
37 {
38+ hostapd_deinit_ht(iface);
39     hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
40     iface->hw_features = NULL;
41     os_free(iface->current_rates);
42--- a/src/ap/hostapd.h
43+++ b/src/ap/hostapd.h
44@@ -226,6 +226,9 @@ struct hostapd_iface {
45     /* Overlapping BSS information */
46     int olbc_ht;
47 
48+ int force_20mhz;
49+ struct os_time last_20mhz_trigger;
50+
51     u16 ht_op_mode;
52     void (*scan_cb)(struct hostapd_iface *iface);
53 
54--- a/src/ap/ieee802_11.c
55+++ b/src/ap/ieee802_11.c
56@@ -1193,6 +1193,9 @@ static void handle_beacon(struct hostapd
57                          sizeof(mgmt->u.beacon)), &elems,
58                       0);
59 
60+ if (!elems.ht_capabilities)
61+ hostapd_trigger_20mhz(hapd->iface);
62+
63     ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
64 }
65 
66--- a/src/ap/ieee802_11.h
67+++ b/src/ap/ieee802_11.h
68@@ -77,4 +77,17 @@ u8 * hostapd_eid_time_zone(struct hostap
69 int hostapd_update_time_adv(struct hostapd_data *hapd);
70 void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
71 
72+#ifdef CONFIG_IEEE80211N
73+void hostapd_trigger_20mhz(struct hostapd_iface *iface);
74+void hostapd_deinit_ht(struct hostapd_iface *iface);
75+
76+#else
77+static inline void hostapd_deinit_ht(struct hostapd_iface *iface)
78+{
79+}
80+static inline void hostapd_trigger_20mhz(struct hostapd_iface *iface)
81+{
82+}
83+#endif /* CONFIG_IEEE80211N */
84+
85 #endif /* IEEE802_11_H */
86--- a/src/ap/ieee802_11_ht.c
87+++ b/src/ap/ieee802_11_ht.c
88@@ -20,9 +20,11 @@
89 #include "drivers/driver.h"
90 #include "hostapd.h"
91 #include "ap_config.h"
92+#include "ap_drv_ops.h"
93 #include "sta_info.h"
94 #include "beacon.h"
95 #include "ieee802_11.h"
96+#include "utils/eloop.h"
97 
98 
99 u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
100@@ -70,12 +72,15 @@ u8 * hostapd_eid_ht_operation(struct hos
101 
102     oper->control_chan = hapd->iconf->channel;
103     oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);
104- if (hapd->iconf->secondary_channel == 1)
105- oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
106- HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
107- if (hapd->iconf->secondary_channel == -1)
108- oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
109- HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
110+
111+ if (!hapd->iface->force_20mhz) {
112+ if (hapd->iconf->secondary_channel == 1)
113+ oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
114+ HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
115+ if (hapd->iconf->secondary_channel == -1)
116+ oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
117+ HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
118+ }
119 
120     pos += sizeof(*oper);
121 
122@@ -271,3 +276,80 @@ void hostapd_get_ht_capab(struct hostapd
123 
124     neg_ht_cap->ht_capabilities_info = host_to_le16(cap);
125 }
126+
127+static void hostapd_set_force_20mhz(struct hostapd_iface *iface);
128+
129+static void hostapd_restore_40mhz(void *eloop_data, void *user_ctx)
130+{
131+ struct hostapd_iface *iface = eloop_data;
132+ struct os_time time;
133+ int timeout;
134+
135+ if (!iface->last_20mhz_trigger.sec)
136+ return;
137+
138+ os_get_time(&time);
139+ timeout = iface->last_20mhz_trigger.sec + iface->conf->dynamic_ht40 -
140+ time.sec;
141+
142+ if (timeout > 0) {
143+ eloop_register_timeout(timeout, 0, hostapd_restore_40mhz,
144+ iface, NULL);
145+ return;
146+ }
147+
148+ iface->last_20mhz_trigger.sec = 0;
149+ iface->last_20mhz_trigger.usec = 0;
150+
151+ iface->force_20mhz = 0;
152+ hostapd_set_force_20mhz(iface);
153+}
154+
155+static void hostapd_set_force_20mhz(struct hostapd_iface *iface)
156+{
157+ int secondary_channel;
158+ int i;
159+
160+ ieee802_11_set_beacons(iface);
161+
162+ for (i = 0; i < iface->num_bss; i++) {
163+ struct hostapd_data *hapd = iface->bss[i];
164+
165+ if (iface->force_20mhz)
166+ secondary_channel = 0;
167+ else
168+ secondary_channel = hapd->iconf->secondary_channel;
169+
170+ if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
171+ hapd->iconf->channel,
172+ hapd->iconf->ieee80211n,
173+ secondary_channel)) {
174+ wpa_printf(MSG_ERROR, "Could not set channel for "
175+ "kernel driver");
176+ }
177+ }
178+}
179+
180+void hostapd_deinit_ht(struct hostapd_iface *iface)
181+{
182+ eloop_cancel_timeout(hostapd_restore_40mhz, iface, NULL);
183+}
184+
185+void hostapd_trigger_20mhz(struct hostapd_iface *iface)
186+{
187+ if (!iface->conf->dynamic_ht40)
188+ return;
189+
190+ if (!iface->force_20mhz) {
191+ iface->force_20mhz = 1;
192+ hostapd_set_force_20mhz(iface);
193+ }
194+
195+ if (!iface->last_20mhz_trigger.sec) {
196+ eloop_cancel_timeout(hostapd_restore_40mhz, iface, NULL);
197+ eloop_register_timeout(iface->conf->dynamic_ht40, 0,
198+ hostapd_restore_40mhz, iface, NULL);
199+ }
200+
201+ os_get_time(&iface->last_20mhz_trigger);
202+}
203

Archive Download this file



interactive