blob: a4fb26bdce51c154d5d168d074c1d016124e5ef6 [file] [log] [blame]
developer2b3caa72022-01-21 13:49:42 +08001From a2dcc0845430159d30e4a1f2054911e38ea09b60 Mon Sep 17 00:00:00 2001
developerdd6437e2022-01-20 16:45:58 +08002From: "howard.hsu" <howard-yh.hsu@mediatek.com>
3Date: Thu, 20 Jan 2022 16:39:04 +0800
4Subject: [PATCH] Add hostapd patches for WiFi Certification MBO test plan
5
6---
developer2b3caa72022-01-21 13:49:42 +08007 ...hbor_count-and-hostapd_neighbor_inse.patch | 72 +++++++++++++
8 ...g-neighbor-report-elements-in-ANQP-r.patch | 95 ++++++++++++++++
9 ...g-neignbor-report-elements-in-BTM-re.patch | 68 ++++++++++++
10 ...ing-BSS-Termination-TSF-by-using-hos.patch | 66 ++++++++++++
11 ...erface-if-BSS-Termination-TSF-is-set.patch | 47 ++++++++
12 ...assoc_frame_timer-to-send-disassocia.patch | 63 +++++++++++
13 ...g-neighbor-report-elements-in-BTM-re.patch | 31 ++++++
14 ...hostapd_neighbor_set_own_report_pref.patch | 88 +++++++++++++++
15 ...d_neighbor_set_pref_by_non_pref_chan.patch | 101 ++++++++++++++++++
16 9 files changed, 631 insertions(+)
developerdd6437e2022-01-20 16:45:58 +080017 create mode 100644 package/network/services/hostapd/patches/902-master-Add-hostapd_neighbor_count-and-hostapd_neighbor_inse.patch
18 create mode 100644 package/network/services/hostapd/patches/903-master-Support-including-neighbor-report-elements-in-ANQP-r.patch
developerdd6437e2022-01-20 16:45:58 +080019 create mode 100644 package/network/services/hostapd/patches/904-master-Support-including-neignbor-report-elements-in-BTM-re.patch
developerdd6437e2022-01-20 16:45:58 +080020 create mode 100644 package/network/services/hostapd/patches/905-master-Support-configuring-BSS-Termination-TSF-by-using-hos.patch
21 create mode 100644 package/network/services/hostapd/patches/906-master-Disable-interface-if-BSS-Termination-TSF-is-set.patch
22 create mode 100644 package/network/services/hostapd/patches/907-master-Add-set_send_disassoc_frame_timer-to-send-disassocia.patch
23 create mode 100644 package/network/services/hostapd/patches/908-master-Support-including-neighbor-report-elements-in-BTM-re.patch
24 create mode 100644 package/network/services/hostapd/patches/909-master-Add-hostapd_neighbor_set_own_report_pref.patch
25 create mode 100644 package/network/services/hostapd/patches/910-master-Add-hostapd_neighbor_set_pref_by_non_pref_chan.patch
26
27diff --git a/package/network/services/hostapd/patches/902-master-Add-hostapd_neighbor_count-and-hostapd_neighbor_inse.patch b/package/network/services/hostapd/patches/902-master-Add-hostapd_neighbor_count-and-hostapd_neighbor_inse.patch
28new file mode 100644
29index 0000000..3a7e018
30--- /dev/null
31+++ b/package/network/services/hostapd/patches/902-master-Add-hostapd_neighbor_count-and-hostapd_neighbor_inse.patch
32@@ -0,0 +1,72 @@
33+From e53d12c69846446bd38a8d05f5a99d79e7907733 Mon Sep 17 00:00:00 2001
34+From: "howard.hsu" <howard-yh.hsu@mediatek.com>
35+Date: Wed, 19 Jan 2022 19:18:07 +0800
36+Subject: [PATCH 1/9] Add hostapd_neighbor_count() and
37+ hostapd_neighbor_insert_buffer ()
38+
39+The first function can count the number of neighbor report in neighbore report
40+database. The second can iterate neighbor report database to build up neighbor
41+report data.
42+---
43+ src/ap/neighbor_db.c | 32 ++++++++++++++++++++++++++++++++
44+ src/ap/neighbor_db.h | 3 +++
45+ 2 files changed, 35 insertions(+)
46+
47+diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
48+index 2bbe318..a47afd4 100644
49+--- a/src/ap/neighbor_db.c
50++++ b/src/ap/neighbor_db.c
51+@@ -88,6 +88,38 @@ int hostapd_neighbor_show(struct hostapd_data *hapd, char *buf, size_t buflen)
52+ }
53+
54+
55++int hostapd_neighbor_count(struct hostapd_data *hapd)
56++{
57++ struct hostapd_neighbor_entry *nr;
58++ int count = 0;
59++
60++ dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
61++ list) {
62++ count++;
63++ }
64++ return count;
65++}
66++
67++
68++int hostapd_neighbor_insert_buffer(struct hostapd_data *hapd, char *buf,
69++ size_t buflen)
70++{
71++ struct hostapd_neighbor_entry *nr;
72++ char *pos = buf;
73++
74++ dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
75++ list) {
76++ /* For neighbor report IE, we only need bssid and nr*/
77++ *pos++ = WLAN_EID_NEIGHBOR_REPORT;
78++ *pos++ = wpabuf_len(nr->nr);
79++ os_memcpy(pos, wpabuf_head(nr->nr), wpabuf_len(nr->nr));
80++ pos += wpabuf_len(nr->nr);
81++ }
82++
83++ return pos - buf;
84++}
85++
86++
87+ static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr)
88+ {
89+ wpabuf_free(nr->nr);
90+diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h
91+index bed0a2f..e93d1d5 100644
92+--- a/src/ap/neighbor_db.h
93++++ b/src/ap/neighbor_db.h
94+@@ -23,4 +23,7 @@ int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
95+ const struct wpa_ssid_value *ssid);
96+ void hostapd_free_neighbor_db(struct hostapd_data *hapd);
97+
98++int hostapd_neighbor_count(struct hostapd_data *hapd);
99++int hostapd_neighbor_insert_buffer(struct hostapd_data *hapd, char *buf,
100++ size_t buflen);
101+ #endif /* NEIGHBOR_DB_H */
102+--
103+2.18.0
104+
105diff --git a/package/network/services/hostapd/patches/903-master-Support-including-neighbor-report-elements-in-ANQP-r.patch b/package/network/services/hostapd/patches/903-master-Support-including-neighbor-report-elements-in-ANQP-r.patch
106new file mode 100644
107index 0000000..73c0052
108--- /dev/null
109+++ b/package/network/services/hostapd/patches/903-master-Support-including-neighbor-report-elements-in-ANQP-r.patch
110@@ -0,0 +1,95 @@
111+From 3111458bed644db0795942e825c65a14c7c12b7b Mon Sep 17 00:00:00 2001
112+From: "howard.hsu" <howard-yh.hsu@mediatek.com>
113+Date: Wed, 19 Jan 2022 19:25:05 +0800
114+Subject: [PATCH 2/9] Support including neighbor report elements in ANQP
115+ response
116+
117+---
118+ src/ap/gas_serv.c | 29 +++++++++++++++++++++++++++++
119+ src/ap/gas_serv.h | 2 ++
120+ 2 files changed, 31 insertions(+)
121+
122+diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
123+index 90f1577..5845ff8 100644
124+--- a/src/ap/gas_serv.c
125++++ b/src/ap/gas_serv.c
126+@@ -19,6 +19,7 @@
127+ #include "dpp_hostapd.h"
128+ #include "sta_info.h"
129+ #include "gas_serv.h"
130++#include "neighbor_db.h"
131+
132+
133+ #ifdef CONFIG_DPP
134+@@ -369,6 +370,24 @@ static void anqp_add_network_auth_type(struct hostapd_data *hapd,
135+ }
136+ }
137+
138++static void anqp_add_neighbor_report(struct hostapd_data *hapd,
139++ struct wpabuf *buf)
140++{
141++ struct hostapd_neighbor_entry *nr;
142++ u8 *len_pos = gas_anqp_add_element(buf, ANQP_NEIGHBOR_REPORT);
143++ if (dl_list_empty(&hapd->nr_db)) {
144++ wpabuf_put_le16(buf, 0);
145++ }
146++ else {
147++ dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list ) {
148++ wpabuf_put_u8(buf, WLAN_EID_NEIGHBOR_REPORT);
149++ wpabuf_put_u8(buf, wpabuf_len(nr->nr));
150++ wpabuf_put_buf(buf, nr->nr);
151++ }
152++ }
153++ gas_anqp_set_element_len(buf, len_pos);
154++}
155++
156+
157+ static void anqp_add_roaming_consortium(struct hostapd_data *hapd,
158+ struct wpabuf *buf)
159+@@ -986,6 +1005,9 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
160+ len += 1000;
161+ if (request & ANQP_REQ_ICON_REQUEST)
162+ len += 65536;
163++ if (request & ANQP_REQ_NEIGHBOR_REPORT) {
164++ len += (40 * hostapd_neighbor_count(hapd));
165++ }
166+ #ifdef CONFIG_FILS
167+ if (request & ANQP_FILS_REALM_INFO)
168+ len += 2 * dl_list_len(&hapd->conf->fils_realms);
169+@@ -1028,6 +1050,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
170+ anqp_add_elem(hapd, buf, ANQP_TDLS_CAPABILITY);
171+ if (request & ANQP_REQ_EMERGENCY_NAI)
172+ anqp_add_elem(hapd, buf, ANQP_EMERGENCY_NAI);
173++ if (request & ANQP_REQ_NEIGHBOR_REPORT)
174++ anqp_add_neighbor_report(hapd, buf);
175+
176+ for (i = 0; i < num_extra_req; i++) {
177+ #ifdef CONFIG_FILS
178+@@ -1172,6 +1196,11 @@ static void rx_anqp_query_list_id(struct hostapd_data *hapd, u16 info_id,
179+ "Emergency NAI",
180+ get_anqp_elem(hapd, info_id) != NULL, qi);
181+ break;
182++ case ANQP_NEIGHBOR_REPORT:
183++ set_anqp_req(ANQP_REQ_NEIGHBOR_REPORT,
184++ "Neighbor Report",
185++ get_anqp_elem(hapd, info_id) != NULL, qi);
186++ break;
187+ default:
188+ #ifdef CONFIG_FILS
189+ if (info_id == ANQP_FILS_REALM_INFO &&
190+diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h
191+index 1528af4..d0241f2 100644
192+--- a/src/ap/gas_serv.h
193++++ b/src/ap/gas_serv.h
194+@@ -40,6 +40,8 @@
195+ (1 << (ANQP_TDLS_CAPABILITY - ANQP_QUERY_LIST))
196+ #define ANQP_REQ_EMERGENCY_NAI \
197+ (1 << (ANQP_EMERGENCY_NAI - ANQP_QUERY_LIST))
198++#define ANQP_REQ_NEIGHBOR_REPORT \
199++ (1 << (ANQP_NEIGHBOR_REPORT - ANQP_QUERY_LIST))
200+ /*
201+ * First 15 Hotspot 2.0 vendor specific ANQP-elements can be included in the
202+ * optimized bitmap.
203+--
204+2.18.0
205+
developerdd6437e2022-01-20 16:45:58 +0800206diff --git a/package/network/services/hostapd/patches/904-master-Support-including-neignbor-report-elements-in-BTM-re.patch b/package/network/services/hostapd/patches/904-master-Support-including-neignbor-report-elements-in-BTM-re.patch
207new file mode 100644
208index 0000000..504c738
209--- /dev/null
210+++ b/package/network/services/hostapd/patches/904-master-Support-including-neignbor-report-elements-in-BTM-re.patch
211@@ -0,0 +1,68 @@
212+From 67e43b33cc70e63e6eabf571ac2c134a5e25b665 Mon Sep 17 00:00:00 2001
213+From: "howard.hsu" <howard-yh.hsu@mediatek.com>
214+Date: Wed, 19 Jan 2022 19:49:09 +0800
215+Subject: [PATCH 3/9] Support including neignbor report elements in BTM
216+ response
217+
218+---
219+ src/ap/wnm_ap.c | 25 +++++++++++++++++++++++--
220+ 1 file changed, 23 insertions(+), 2 deletions(-)
221+
222+diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
223+index 2f66a54..e37ddd0 100644
224+--- a/src/ap/wnm_ap.c
225++++ b/src/ap/wnm_ap.c
226+@@ -20,6 +20,7 @@
227+ #include "ap/wpa_auth.h"
228+ #include "mbo_ap.h"
229+ #include "wnm_ap.h"
230++#include "ap/neighbor_db.h"
231+
232+ #define MAX_TFS_IE_LEN 1024
233+
234+@@ -370,9 +371,21 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
235+ u8 *pos;
236+ int res;
237+
238+- mgmt = os_zalloc(sizeof(*mgmt));
239+- if (mgmt == NULL)
240++ int nr_num = hostapd_neighbor_count(hapd);
241++ int nr_size = ETH_ALEN + 4 + 1 + 1 + 1 + 5;
242++ int total_nr_size = nr_num * nr_size;
243++ u8 *nr_data = os_malloc(total_nr_size);
244++ int nr_data_len = 0;
245++ if(nr_data == NULL) {
246++ wpa_printf (MSG_ERROR, "Failed to allocate memory");
247++ } else {
248++ nr_data_len = hostapd_neighbor_insert_buffer(hapd, nr_data, total_nr_size);
249++ }
250++ mgmt = os_zalloc(sizeof(*mgmt) + nr_data_len);
251++ if (mgmt == NULL) {
252++ wpa_printf (MSG_ERROR, "Failed to allocate memory for mgmt frame");
253+ return -1;
254++ }
255+ os_memcpy(mgmt->da, addr, ETH_ALEN);
256+ os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
257+ os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
258+@@ -382,10 +395,18 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
259+ mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
260+ mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
261+ mgmt->u.action.u.bss_tm_req.req_mode = 0;
262++ if(nr_num) {
263++ mgmt->u.action.u.bss_tm_req.req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED;
264++ }
265+ mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
266+ mgmt->u.action.u.bss_tm_req.validity_interval = 1;
267+ pos = mgmt->u.action.u.bss_tm_req.variable;
268+
269++ if(nr_num) {
270++ os_memcpy(pos, nr_data, nr_data_len);
271++ pos += nr_data_len;
272++ }
273++
274+ hapd->openwrt_stats.wnm.bss_transition_request_tx++;
275+ wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
276+ MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
277+--
278+2.18.0
279+
developerdd6437e2022-01-20 16:45:58 +0800280diff --git a/package/network/services/hostapd/patches/905-master-Support-configuring-BSS-Termination-TSF-by-using-hos.patch b/package/network/services/hostapd/patches/905-master-Support-configuring-BSS-Termination-TSF-by-using-hos.patch
281new file mode 100644
282index 0000000..2f9b174
283--- /dev/null
284+++ b/package/network/services/hostapd/patches/905-master-Support-configuring-BSS-Termination-TSF-by-using-hos.patch
285@@ -0,0 +1,66 @@
286+From b97cdd75ea3f0c15a6d76cd6483941ee73fa400c Mon Sep 17 00:00:00 2001
287+From: "howard.hsu" <howard-yh.hsu@mediatek.com>
288+Date: Wed, 19 Jan 2022 20:20:03 +0800
289+Subject: [PATCH 4/9] Support configuring BSS Termination TSF by using
290+ hostapd_cli command
291+
292+---
293+ hostapd/ctrl_iface.c | 9 +++++++++
294+ src/ap/ap_config.c | 1 +
295+ src/ap/ap_config.h | 1 +
296+ 3 files changed, 11 insertions(+)
297+
298+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
299+index 568232a..cb2bdbf 100644
300+--- a/hostapd/ctrl_iface.c
301++++ b/hostapd/ctrl_iface.c
302+@@ -954,6 +954,10 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
303+ wpa_printf(MSG_DEBUG, "Invalid bss_term data");
304+ return -1;
305+ }
306++ if (hapd->conf->bss_termination_tsf) {
307++ WPA_PUT_LE64(&bss_term_dur[2], hapd->conf->bss_termination_tsf);
308++ }
309++
310+ end++;
311+ WPA_PUT_LE16(&bss_term_dur[10], atoi(end));
312+ }
313+@@ -1589,6 +1593,11 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
314+ #endif /* CONFIG_DPP */
315+ } else if (os_strcasecmp(cmd, "setband") == 0) {
316+ ret = hostapd_ctrl_iface_set_band(hapd, value);
317++ } else if (os_strcasecmp(cmd, "bss_termination_tsf") == 0) {
318++ int termination_sec = atoi(value);
319++ hapd->conf->bss_termination_tsf = termination_sec;
320++ wpa_printf(MSG_DEBUG, "BSS Termination TSF: value = %d",
321++ termination_sec);
322+ } else {
323+ ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value);
324+ if (ret)
325+diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
326+index ce281ac..fc1372a 100644
327+--- a/src/ap/ap_config.c
328++++ b/src/ap/ap_config.c
329+@@ -170,6 +170,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
330+ /* comeback after 10 TUs */
331+ bss->pasn_comeback_after = 10;
332+ #endif /* CONFIG_PASN */
333++ bss->bss_termination_tsf = 0;
334+ }
335+
336+
337+diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
338+index ffc3c2c..1f3f3d8 100644
339+--- a/src/ap/ap_config.h
340++++ b/src/ap/ap_config.h
341+@@ -549,6 +549,7 @@ struct hostapd_bss_config {
342+ int wnm_sleep_mode;
343+ int wnm_sleep_mode_no_keys;
344+ int bss_transition;
345++ unsigned int bss_termination_tsf;
346+
347+ /* IEEE 802.11u - Interworking */
348+ int interworking;
349+--
350+2.18.0
351+
352diff --git a/package/network/services/hostapd/patches/906-master-Disable-interface-if-BSS-Termination-TSF-is-set.patch b/package/network/services/hostapd/patches/906-master-Disable-interface-if-BSS-Termination-TSF-is-set.patch
353new file mode 100644
354index 0000000..18b44fa
355--- /dev/null
356+++ b/package/network/services/hostapd/patches/906-master-Disable-interface-if-BSS-Termination-TSF-is-set.patch
357@@ -0,0 +1,47 @@
358+From d084074baaa8f9df15810323aeeeba0e98b0dbd5 Mon Sep 17 00:00:00 2001
359+From: "howard.hsu" <howard-yh.hsu@mediatek.com>
360+Date: Wed, 19 Jan 2022 21:03:38 +0800
361+Subject: [PATCH 5/9] Disable interface if BSS Termination TSF is set
362+
363+---
364+ src/ap/wnm_ap.c | 17 +++++++++++++++++
365+ 1 file changed, 17 insertions(+)
366+
367+diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
368+index e37ddd0..ce7aca2 100644
369+--- a/src/ap/wnm_ap.c
370++++ b/src/ap/wnm_ap.c
371+@@ -767,6 +767,22 @@ static void set_disassoc_timer(struct hostapd_data *hapd, struct sta_info *sta,
372+ }
373+
374+
375++void bss_termination_disable_iface(void *eloop_ctx, void *timeout_ctx)
376++{
377++ struct hostapd_data *hapd = eloop_ctx;
378++ hostapd_disable_iface(hapd->iface);
379++}
380++
381++
382++static void set_disable_iface_timer(struct hostapd_data *hapd, struct sta_info *sta,
383++ int disable_iface_timer)
384++{
385++ wpa_printf(MSG_DEBUG, "Disable interface timer set to %d secs", disable_iface_timer);
386++ eloop_register_timeout(disable_iface_timer, 0,
387++ bss_termination_disable_iface, hapd, NULL);
388++}
389++
390++
391+ int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd,
392+ struct sta_info *sta, const char *url,
393+ int disassoc_timer)
394+@@ -855,6 +871,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
395+ bss_term_dur) {
396+ os_memcpy(pos, bss_term_dur, 12);
397+ pos += 12;
398++ set_disable_iface_timer(hapd, sta, hapd->conf->bss_termination_tsf);
399+ }
400+
401+ if (url) {
402+--
403+2.18.0
404+
405diff --git a/package/network/services/hostapd/patches/907-master-Add-set_send_disassoc_frame_timer-to-send-disassocia.patch b/package/network/services/hostapd/patches/907-master-Add-set_send_disassoc_frame_timer-to-send-disassocia.patch
406new file mode 100644
407index 0000000..8839c25
408--- /dev/null
409+++ b/package/network/services/hostapd/patches/907-master-Add-set_send_disassoc_frame_timer-to-send-disassocia.patch
410@@ -0,0 +1,63 @@
411+From 1f4ff04758932b773df99a51055373f7610046ce Mon Sep 17 00:00:00 2001
412+From: "howard.hsu" <howard-yh.hsu@mediatek.com>
413+Date: Wed, 19 Jan 2022 21:15:07 +0800
414+Subject: [PATCH 6/9] Add set_send_disassoc_frame_timer() to send disassociate
415+ frame
416+
417+Function set_disassoc_timer() may fail if key was deleted first. This new
418+function will not ask to delete key as set_disassoc_timer() did.
419+---
420+ src/ap/wnm_ap.c | 30 +++++++++++++++++++++++++++++-
421+ 1 file changed, 29 insertions(+), 1 deletion(-)
422+
423+diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
424+index ce7aca2..2ee9fb7 100644
425+--- a/src/ap/wnm_ap.c
426++++ b/src/ap/wnm_ap.c
427+@@ -767,6 +767,34 @@ static void set_disassoc_timer(struct hostapd_data *hapd, struct sta_info *sta,
428+ }
429+
430+
431++static void set_send_disassoc_frame_timer(struct hostapd_data *hapd, struct sta_info *sta,
432++ int disassoc_timer)
433++{
434++ int timeout, beacon_int;
435++
436++ /*
437++ * Prevent STA from reconnecting using cached PMKSA to force
438++ * full authentication with the authentication server (which may
439++ * decide to reject the connection),
440++ */
441++ wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
442++
443++ beacon_int = hapd->iconf->beacon_int;
444++ if (beacon_int < 1)
445++ beacon_int = 100; /* best guess */
446++ /* Calculate timeout in ms based on beacon_int in TU */
447++ timeout = disassoc_timer * beacon_int * 128 / 125;
448++ wpa_printf(MSG_DEBUG, "Disassociation timer for " MACSTR
449++ " set to %d ms", MAC2STR(sta->addr), timeout);
450++
451++ u16 reason = WLAN_REASON_PREV_AUTH_NOT_VALID;
452++
453++ hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
454++ if (sta)
455++ ap_sta_disassociate(hapd, sta, reason);
456++}
457++
458++
459+ void bss_termination_disable_iface(void *eloop_ctx, void *timeout_ctx)
460+ {
461+ struct hostapd_data *hapd = eloop_ctx;
462+@@ -908,7 +936,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
463+ hapd->openwrt_stats.wnm.bss_transition_request_tx++;
464+ if (disassoc_timer) {
465+ /* send disassociation frame after time-out */
466+- set_disassoc_timer(hapd, sta, disassoc_timer);
467++ set_send_disassoc_frame_timer(hapd, sta, disassoc_timer);
468+ }
469+
470+ return 0;
471+--
472+2.18.0
473+
474diff --git a/package/network/services/hostapd/patches/908-master-Support-including-neighbor-report-elements-in-BTM-re.patch b/package/network/services/hostapd/patches/908-master-Support-including-neighbor-report-elements-in-BTM-re.patch
475new file mode 100644
476index 0000000..dd6a859
477--- /dev/null
478+++ b/package/network/services/hostapd/patches/908-master-Support-including-neighbor-report-elements-in-BTM-re.patch
479@@ -0,0 +1,31 @@
480+From f0b8ae8248f026c31e19a9c04423013a720f6136 Mon Sep 17 00:00:00 2001
481+From: "howard.hsu" <howard-yh.hsu@mediatek.com>
482+Date: Wed, 19 Jan 2022 21:16:45 +0800
483+Subject: [PATCH 7/9] Support including neighbor report elements in BTM request
484+
485+---
486+ hostapd/ctrl_iface.c | 7 ++++++-
487+ 1 file changed, 6 insertions(+), 1 deletion(-)
488+
489+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
490+index cb2bdbf..2c5cf4b 100644
491+--- a/hostapd/ctrl_iface.c
492++++ b/hostapd/ctrl_iface.c
493+@@ -984,8 +984,13 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
494+ req_mode |= WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT;
495+ }
496+
497+- if (os_strstr(cmd, " pref=1"))
498++ if (os_strstr(cmd, " pref=1")) {
499+ req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED;
500++ if (nei_len == 0) {
501++ // Add neigibor report from neighbor report db to nei_rep buffer
502++ nei_len = hostapd_neighbor_insert_buffer (hapd, nei_rep, 1000);
503++ }
504++ }
505+ if (os_strstr(cmd, " abridged=1"))
506+ req_mode |= WNM_BSS_TM_REQ_ABRIDGED;
507+ if (os_strstr(cmd, " disassoc_imminent=1"))
508+--
509+2.18.0
510+
511diff --git a/package/network/services/hostapd/patches/909-master-Add-hostapd_neighbor_set_own_report_pref.patch b/package/network/services/hostapd/patches/909-master-Add-hostapd_neighbor_set_own_report_pref.patch
512new file mode 100644
513index 0000000..4e233d4
514--- /dev/null
515+++ b/package/network/services/hostapd/patches/909-master-Add-hostapd_neighbor_set_own_report_pref.patch
516@@ -0,0 +1,88 @@
517+From de5785cfdbc90d789a9b20e160b7311a2a3841e9 Mon Sep 17 00:00:00 2001
518+From: "howard.hsu" <howard-yh.hsu@mediatek.com>
519+Date: Wed, 19 Jan 2022 21:27:55 +0800
520+Subject: [PATCH 8/9] Add hostapd_neighbor_set_own_report_pref()
521+
522+If my own BSS is going to terminate itself, the preference value of neighbor
523+report must be set to 0.
524+---
525+ hostapd/ctrl_iface.c | 5 ++++-
526+ src/ap/neighbor_db.c | 36 ++++++++++++++++++++++++++++++++++++
527+ src/ap/neighbor_db.h | 2 ++
528+ 3 files changed, 42 insertions(+), 1 deletion(-)
529+
530+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
531+index 2c5cf4b..5be75e5 100644
532+--- a/hostapd/ctrl_iface.c
533++++ b/hostapd/ctrl_iface.c
534+@@ -993,8 +993,11 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
535+ }
536+ if (os_strstr(cmd, " abridged=1"))
537+ req_mode |= WNM_BSS_TM_REQ_ABRIDGED;
538+- if (os_strstr(cmd, " disassoc_imminent=1"))
539++ if (os_strstr(cmd, " disassoc_imminent=1")) {
540+ req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT;
541++ /* Set own BSS neighbor report preference value as 0 */
542++ hostapd_neighbor_set_own_report_pref(hapd, nei_rep, nei_len, 0);
543++ }
544+
545+ #ifdef CONFIG_MBO
546+ pos = os_strstr(cmd, "mbo=");
547+diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
548+index a47afd4..6473800 100644
549+--- a/src/ap/neighbor_db.c
550++++ b/src/ap/neighbor_db.c
551+@@ -348,3 +348,39 @@ void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
552+ wpabuf_free(nr);
553+ #endif /* NEED_AP_MLME */
554+ }
555++
556++
557++void hostapd_neighbor_set_own_report_pref(struct hostapd_data *hapd, char *nei_buf,
558++ size_t buflen, const int pref)
559++{
560++ struct hostapd_neighbor_entry *nr;
561++ char *pos, *next_nr;
562++
563++ pos = nei_buf;
564++ next_nr = nei_buf;
565++
566++ dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
567++ list) {
568++ pos = next_nr;
569++ next_nr = pos + 2 + wpabuf_len(nr->nr);
570++ /* Shift 2 bytes for Element ID and Neighbor report length */
571++ pos = pos + 2;
572++ if(os_memcmp(pos, hapd->own_addr, ETH_ALEN) == 0) {
573++ /* Shift for BSSID + BSSID info + Op_class + channel num + PHY type */
574++ pos = pos + 6 + 4 + 1 + 1 + 1;
575++
576++ /* Iterate Subelement */
577++ while (next_nr - pos > 0) {
578++ if (*pos == 3) {
579++ pos = pos + 2;
580++ *pos = pref;
581++ return;
582++ } else {
583++ pos++;
584++ int shift_len = *pos++;
585++ pos = pos + shift_len;
586++ }
587++ }
588++ }
589++ }
590++}
591+diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h
592+index e93d1d5..dc6807b 100644
593+--- a/src/ap/neighbor_db.h
594++++ b/src/ap/neighbor_db.h
595+@@ -26,4 +26,6 @@ void hostapd_free_neighbor_db(struct hostapd_data *hapd);
596+ int hostapd_neighbor_count(struct hostapd_data *hapd);
597+ int hostapd_neighbor_insert_buffer(struct hostapd_data *hapd, char *buf,
598+ size_t buflen);
599++void hostapd_neighbor_set_own_report_pref(struct hostapd_data *hapd, char *nei_buf,
600++ size_t buflen, const int pref);
601+ #endif /* NEIGHBOR_DB_H */
602+--
603+2.18.0
604+
605diff --git a/package/network/services/hostapd/patches/910-master-Add-hostapd_neighbor_set_pref_by_non_pref_chan.patch b/package/network/services/hostapd/patches/910-master-Add-hostapd_neighbor_set_pref_by_non_pref_chan.patch
606new file mode 100644
607index 0000000..b38b216
608--- /dev/null
609+++ b/package/network/services/hostapd/patches/910-master-Add-hostapd_neighbor_set_pref_by_non_pref_chan.patch
610@@ -0,0 +1,101 @@
611+From 3306cdad16655901c1b76372fa939eae20ac8b26 Mon Sep 17 00:00:00 2001
612+From: "howard.hsu" <howard-yh.hsu@mediatek.com>
613+Date: Wed, 19 Jan 2022 21:32:17 +0800
614+Subject: [PATCH 9/9] Add hostapd_neighbor_set_pref_by_non_pref_chan()
615+
616+The preference value of neighbor report shall be modified according to struct
617+non_pref_chan_info.
618+---
619+ hostapd/ctrl_iface.c | 2 ++
620+ src/ap/neighbor_db.c | 51 ++++++++++++++++++++++++++++++++++++++++++++
621+ src/ap/neighbor_db.h | 4 ++++
622+ 3 files changed, 57 insertions(+)
623+
624+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
625+index 5be75e5..2e11e7b 100644
626+--- a/hostapd/ctrl_iface.c
627++++ b/hostapd/ctrl_iface.c
628+@@ -999,6 +999,8 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
629+ hostapd_neighbor_set_own_report_pref(hapd, nei_rep, nei_len, 0);
630+ }
631+
632++ hostapd_neighbor_set_pref_by_non_pref_chan(hapd, sta, nei_rep, nei_len);
633++
634+ #ifdef CONFIG_MBO
635+ pos = os_strstr(cmd, "mbo=");
636+ if (pos) {
637+diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
638+index 6473800..254dc39 100644
639+--- a/src/ap/neighbor_db.c
640++++ b/src/ap/neighbor_db.c
641+@@ -384,3 +384,54 @@ void hostapd_neighbor_set_own_report_pref(struct hostapd_data *hapd, char *nei_b
642+ }
643+ }
644+ }
645++
646++#ifdef CONFIG_MBO
647++void hostapd_neighbor_set_pref_by_non_pref_chan(struct hostapd_data *hapd,
648++ struct sta_info* sta, char *nei_buf, size_t buflen)
649++{
650++ struct hostapd_neighbor_entry *nr;
651++ struct mbo_non_pref_chan_info *info;
652++ u8 i;
653++
654++ for(info = sta->non_pref_chan; info; info = info->next) {
655++ /* Check OP_Class and Channel num */
656++ for(i = 0; i < info->num_channels; i++) {
657++ char *pos, *next_nr;
658++
659++ pos = nei_buf;
660++ next_nr = nei_buf;
661++
662++ /* Iterate Neighbor report database */
663++ dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
664++ list) {
665++ pos = next_nr;
666++ next_nr = pos + 2 + wpabuf_len(nr->nr);
667++ /**
668++ * Shift 12 bytes for Element ID, Neighbor report length,
669++ * BSSID and BSSID info.
670++ */
671++ pos = pos + 12;
672++ int nr_op_class = *pos++;
673++ int nr_channel = *pos;
674++ if(info->op_class == nr_op_class && info->channels[i] == nr_channel) {
675++ /* Shift for Channel Num + PHY type */
676++ pos = pos + 1 + 1;
677++
678++ // Iterate Subelement
679++ while(next_nr - pos > 0) {
680++ if(*pos == 3) {
681++ pos = pos + 2;
682++ *pos = info->pref;
683++ break;
684++ }else {
685++ pos++;
686++ int shift_len = *pos++;
687++ pos = pos + shift_len;
688++ }
689++ }
690++ }
691++ }
692++ }
693++ }
694++}
695++#endif
696+diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h
697+index dc6807b..731d1b8 100644
698+--- a/src/ap/neighbor_db.h
699++++ b/src/ap/neighbor_db.h
700+@@ -28,4 +28,8 @@ int hostapd_neighbor_insert_buffer(struct hostapd_data *hapd, char *buf,
701+ size_t buflen);
702+ void hostapd_neighbor_set_own_report_pref(struct hostapd_data *hapd, char *nei_buf,
703+ size_t buflen, const int pref);
704++#ifdef CONFIG_MBO
705++void hostapd_neighbor_set_pref_by_non_pref_chan(struct hostapd_data *hapd,
706++ struct sta_info* sta, char *nei_buf, size_t buflen);
707++#endif
708+ #endif /* NEIGHBOR_DB_H */
709+--
710+2.18.0
711+
712--
7132.18.0
714