hostapd: provide BSS-transition-queries to ubus subscribers
authorDavid Bauer <mail@david-bauer.net>
Sat, 30 Oct 2021 22:11:51 +0000 (00:11 +0200)
committerDavid Bauer <mail@david-bauer.net>
Sun, 19 Dec 2021 23:15:03 +0000 (00:15 +0100)
Provide incoming BSS transition queries to ubus subscribers.

This allows external steering daemons to provide clients with
an optimal list of transition candidates.

This commit has no functional state in case no ubus subscriber is
present or it does not handle this ubus message.

To prevent hostapd from sending out a generic response by itself, a
subscribing daemon has to return a non-zero response code to hostapd.

Signed-off-by: David Bauer <mail@david-bauer.net>
package/network/services/hostapd/patches/600-ubus_support.patch
package/network/services/hostapd/src/src/ap/ubus.c

index bf2f8a52d1956ab309759fa103ccf286f7fb6103..58313f1ecdf1381e2c67611eb72c4a7c4f0bdd71 100644 (file)
  
 --- a/src/ap/wnm_ap.c
 +++ b/src/ap/wnm_ap.c
-@@ -463,7 +463,7 @@ static void ieee802_11_rx_bss_trans_mgmt
+@@ -441,7 +441,8 @@ static void ieee802_11_rx_bss_trans_mgmt
+       wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries",
+                   pos, end - pos);
+-      ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token);
++      if (!hostapd_ubus_notify_bss_transition_query(hapd, addr, dialog_token, reason, pos, end - pos))
++              ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token);
+ }
+@@ -463,7 +464,7 @@ static void ieee802_11_rx_bss_trans_mgmt
                                              size_t len)
  {
        u8 dialog_token, status_code, bss_termination_delay;
        int enabled = hapd->conf->bss_transition;
        struct sta_info *sta;
  
-@@ -510,6 +510,7 @@ static void ieee802_11_rx_bss_trans_mgmt
+@@ -510,6 +511,7 @@ static void ieee802_11_rx_bss_trans_mgmt
                        wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field");
                        return;
                }
                sta->agreed_to_steer = 1;
                eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta);
                eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer,
-@@ -529,6 +530,10 @@ static void ieee802_11_rx_bss_trans_mgmt
+@@ -529,6 +531,10 @@ static void ieee802_11_rx_bss_trans_mgmt
                        MAC2STR(addr), status_code, bss_termination_delay);
        }
  
index 3e5456e695e92ce8a7bf19f4f5b399ef04161ed7..20ee7c90e7d6d3380d3c473d7f3f94396a7e21a6 100644 (file)
@@ -1850,13 +1850,30 @@ void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequen
        }
 }
 
+#ifdef CONFIG_WNM_AP
+static void hostapd_ubus_notify_bss_transition_add_candidate_list(
+       const u8 *candidate_list, u16 candidate_list_len)
+{
+       char *cl_str;
+       int i;
+
+       if (candidate_list_len == 0)
+               return;
+
+       cl_str = blobmsg_alloc_string_buffer(&b, "candidate-list", candidate_list_len * 2 + 1);
+       for (i = 0; i < candidate_list_len; i++)
+               snprintf(&cl_str[i*2], 3, "%02X", candidate_list[i]);
+       blobmsg_add_string_buffer(&b);
+
+}
+#endif
+
 void hostapd_ubus_notify_bss_transition_response(
        struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code,
        u8 bss_termination_delay, const u8 *target_bssid,
        const u8 *candidate_list, u16 candidate_list_len)
 {
 #ifdef CONFIG_WNM_AP
-       char *cl_str;
        u16 i;
 
        if (!hapd->ubus.obj.has_subscribers)
@@ -1872,13 +1889,45 @@ void hostapd_ubus_notify_bss_transition_response(
        blobmsg_add_u8(&b, "bss-termination-delay", bss_termination_delay);
        if (target_bssid)
                blobmsg_add_macaddr(&b, "target-bssid", target_bssid);
-       if (candidate_list_len > 0) {
-               cl_str = blobmsg_alloc_string_buffer(&b, "candidate-list", candidate_list_len * 2 + 1);
-               for (i = 0; i < candidate_list_len; i++)
-                       snprintf(&cl_str[i*2], 3, "%02X", candidate_list[i]);
-               blobmsg_add_string_buffer(&b);
-       }
+       
+       hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len);
 
        ubus_notify(ctx, &hapd->ubus.obj, "bss-transition-response", b.head, -1);
 #endif
 }
+
+int hostapd_ubus_notify_bss_transition_query(
+       struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason,
+       const u8 *candidate_list, u16 candidate_list_len)
+{
+#ifdef CONFIG_WNM_AP
+       struct ubus_event_req ureq = {};
+       char *cl_str;
+       u16 i;
+
+       if (!hapd->ubus.obj.has_subscribers)
+               return 0;
+
+       if (!addr)
+               return 0;
+
+       blob_buf_init(&b, 0);
+       blobmsg_add_macaddr(&b, "address", addr);
+       blobmsg_add_u8(&b, "dialog-token", dialog_token);
+       blobmsg_add_u8(&b, "reason", reason);
+       hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len);
+
+       if (!hapd->ubus.notify_response) {
+               ubus_notify(ctx, &hapd->ubus.obj, "bss-transition-query", b.head, -1);
+               return 0;
+       }
+
+       if (ubus_notify_async(ctx, &hapd->ubus.obj, "bss-transition-query", b.head, &ureq.nreq))
+               return 0;
+
+       ureq.nreq.status_cb = ubus_event_cb;
+       ubus_complete_request(ctx, &ureq.nreq.req, 100);
+
+       return ureq.resp;
+#endif
+}
\ No newline at end of file