Hi! I tried this patch and at works as expected. Thank you very much!
André Am 07.10.21 um 00:27 schrieb David Bauer: > The existing wnm_disassoc_imminent ubus method only supports issuing a > bss transition request with the disassoc imminent flag set. > For use-cases, where the client is requested to roam to another BSS > without a pending disassoc, this existing method is not suitable. > > Add a new bss_transition_request ubus method, which provides a more > universal way to dispatch a transition request. It takes the following > arguments: > > Required: > addr: String - MAC-address of the STA to send the request to (colon-seperated) > > Optional: > abridged - Bool - Indicates if the abridged flag is set > disassociation_imminent: Bool - Whether or not the disassoc_imminent > flag is set > disassociation_timer: I32 - number of TBTTs after which the client will > be disassociated > validity_period: I32 - number of TBTTs after which the beacon > candidate list (if included) will be invalid > neighbors: blob-array - Array of strings containing neighbor reports as > hex-string > > Signed-off-by: David Bauer <m...@david-bauer.net> > --- > .../services/hostapd/src/src/ap/ubus.c | 152 +++++++++++++----- > 1 file changed, 112 insertions(+), 40 deletions(-) > > diff --git a/package/network/services/hostapd/src/src/ap/ubus.c > b/package/network/services/hostapd/src/src/ap/ubus.c > index 367e1b652b..1b5c60416f 100644 > --- a/package/network/services/hostapd/src/src/ap/ubus.c > +++ b/package/network/services/hostapd/src/src/ap/ubus.c > @@ -1275,60 +1275,30 @@ hostapd_rrm_beacon_req(struct ubus_context *ctx, > struct ubus_object *obj, > > > #ifdef CONFIG_WNM_AP > -enum { > - WNM_DISASSOC_ADDR, > - WNM_DISASSOC_DURATION, > - WNM_DISASSOC_NEIGHBORS, > - WNM_DISASSOC_ABRIDGED, > - __WNM_DISASSOC_MAX, > -}; > - > -static const struct blobmsg_policy wnm_disassoc_policy[__WNM_DISASSOC_MAX] = > { > - [WNM_DISASSOC_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, > - [WNM_DISASSOC_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, > - [WNM_DISASSOC_NEIGHBORS] { "neighbors", BLOBMSG_TYPE_ARRAY }, > - [WNM_DISASSOC_ABRIDGED] { "abridged", BLOBMSG_TYPE_BOOL }, > -}; > > static int > -hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, struct ubus_object > *obj, > - struct ubus_request_data *ureq, const char > *method, > - struct blob_attr *msg) > +hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool > disassoc_imminent, bool abridged, > + u16 disassoc_timer, u8 validity_period, struct blob_attr > *neighbors) > { > - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, > ubus.obj); > - struct blob_attr *tb[__WNM_DISASSOC_MAX]; > struct blob_attr *cur; > struct sta_info *sta; > - int duration = 10; > - int rem; > int nr_len = 0; > + int rem; > u8 *nr = NULL; > - u8 req_mode = WNM_BSS_TM_REQ_DISASSOC_IMMINENT; > - u8 addr[ETH_ALEN]; > - > - blobmsg_parse(wnm_disassoc_policy, __WNM_DISASSOC_MAX, tb, > blob_data(msg), blob_len(msg)); > - > - if (!tb[WNM_DISASSOC_ADDR]) > - return UBUS_STATUS_INVALID_ARGUMENT; > - > - if (hwaddr_aton(blobmsg_data(tb[WNM_DISASSOC_ADDR]), addr)) > - return UBUS_STATUS_INVALID_ARGUMENT; > - > - if ((cur = tb[WNM_DISASSOC_DURATION]) != NULL) > - duration = blobmsg_get_u32(cur); > + u8 req_mode = 0; > > sta = ap_get_sta(hapd, addr); > if (!sta) > return UBUS_STATUS_NOT_FOUND; > > - if (tb[WNM_DISASSOC_NEIGHBORS]) { > + if (neighbors) { > u8 *nr_cur; > > - if (blobmsg_check_array(tb[WNM_DISASSOC_NEIGHBORS], > + if (blobmsg_check_array(neighbors, > BLOBMSG_TYPE_STRING) < 0) > return UBUS_STATUS_INVALID_ARGUMENT; > > - blobmsg_for_each_attr(cur, tb[WNM_DISASSOC_NEIGHBORS], rem) { > + blobmsg_for_each_attr(cur, neighbors, rem) { > int len = strlen(blobmsg_get_string(cur)); > > if (len % 2) > @@ -1344,7 +1314,7 @@ hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, > struct ubus_object *obj, > } > > nr_cur = nr; > - blobmsg_for_each_attr(cur, tb[WNM_DISASSOC_NEIGHBORS], rem) { > + blobmsg_for_each_attr(cur, neighbors, rem) { > int len = strlen(blobmsg_get_string(cur)) / 2; > > *nr_cur++ = WLAN_EID_NEIGHBOR_REPORT; > @@ -1361,15 +1331,116 @@ hostapd_wnm_disassoc_imminent(struct ubus_context > *ctx, struct ubus_object *obj, > if (nr) > req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED; > > - if (tb[WNM_DISASSOC_ABRIDGED] && > blobmsg_get_bool(tb[WNM_DISASSOC_ABRIDGED])) > + if (abridged) > req_mode |= WNM_BSS_TM_REQ_ABRIDGED; > > - if (wnm_send_bss_tm_req(hapd, sta, req_mode, duration, duration, NULL, > + if (disassoc_imminent) > + req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT; > + > + if (wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, > validity_period, NULL, > NULL, nr, nr_len, NULL, 0)) > return UBUS_STATUS_UNKNOWN_ERROR; > > return 0; > } > + > +enum { > + BSS_TR_ADDR, > + BSS_TR_DA_IMMINENT, > + BSS_TR_DA_TIMER, > + BSS_TR_VALID_PERIOD, > + BSS_TR_NEIGHBORS, > + BSS_TR_ABRIDGED, > + __BSS_TR_DISASSOC_MAX > +}; > + > +static const struct blobmsg_policy bss_tr_policy[__BSS_TR_DISASSOC_MAX] = { > + [BSS_TR_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, > + [BSS_TR_DA_IMMINENT] = { "disassociation_imminent", BLOBMSG_TYPE_BOOL }, > + [BSS_TR_DA_TIMER] = { "disassociation_timer", BLOBMSG_TYPE_INT32 }, > + [BSS_TR_VALID_PERIOD] = { "validity_period", BLOBMSG_TYPE_INT32 }, > + [BSS_TR_NEIGHBORS] = { "neighbors", BLOBMSG_TYPE_ARRAY }, > + [BSS_TR_ABRIDGED] = { "abridged", BLOBMSG_TYPE_BOOL }, > +}; > + > +static int > +hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object > *obj, > + struct ubus_request_data *ureq, const char > *method, > + struct blob_attr *msg) > +{ > + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, > ubus.obj); > + struct blob_attr *tb[__BSS_TR_DISASSOC_MAX]; > + struct sta_info *sta; > + u32 da_timer = 0; > + u32 valid_period = 0; > + u8 addr[ETH_ALEN]; > + bool abridged; > + bool da_imminent; > + > + blobmsg_parse(bss_tr_policy, __BSS_TR_DISASSOC_MAX, tb, blob_data(msg), > blob_len(msg)); > + > + if (!tb[BSS_TR_ADDR]) > + return UBUS_STATUS_INVALID_ARGUMENT; > + > + if (hwaddr_aton(blobmsg_data(tb[BSS_TR_ADDR]), addr)) > + return UBUS_STATUS_INVALID_ARGUMENT; > + > + if (tb[BSS_TR_DA_TIMER]) > + da_timer = blobmsg_get_u32(tb[BSS_TR_DA_TIMER]); > + > + if (tb[BSS_TR_VALID_PERIOD]) > + valid_period = blobmsg_get_u32(tb[BSS_TR_VALID_PERIOD]); > + > + da_imminent = !!(tb[BSS_TR_DA_IMMINENT] && > blobmsg_get_bool(tb[BSS_TR_DA_IMMINENT])); > + abridged = !!(tb[BSS_TR_ABRIDGED] && > blobmsg_get_bool(tb[BSS_TR_ABRIDGED])); > + > + return hostapd_bss_tr_send(hapd, addr, da_imminent, abridged, da_timer, > valid_period, > + tb[BSS_TR_NEIGHBORS]); > +} > + > +enum { > + WNM_DISASSOC_ADDR, > + WNM_DISASSOC_DURATION, > + WNM_DISASSOC_NEIGHBORS, > + WNM_DISASSOC_ABRIDGED, > + __WNM_DISASSOC_MAX, > +}; > + > +static const struct blobmsg_policy wnm_disassoc_policy[__WNM_DISASSOC_MAX] = > { > + [WNM_DISASSOC_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, > + [WNM_DISASSOC_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, > + [WNM_DISASSOC_NEIGHBORS] { "neighbors", BLOBMSG_TYPE_ARRAY }, > + [WNM_DISASSOC_ABRIDGED] { "abridged", BLOBMSG_TYPE_BOOL }, > +}; > + > +static int > +hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, struct ubus_object > *obj, > + struct ubus_request_data *ureq, const char > *method, > + struct blob_attr *msg) > +{ > + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, > ubus.obj); > + struct blob_attr *tb[__WNM_DISASSOC_MAX]; > + struct sta_info *sta; > + int duration = 10; > + u8 addr[ETH_ALEN]; > + bool abridged; > + > + blobmsg_parse(wnm_disassoc_policy, __WNM_DISASSOC_MAX, tb, > blob_data(msg), blob_len(msg)); > + > + if (!tb[WNM_DISASSOC_ADDR]) > + return UBUS_STATUS_INVALID_ARGUMENT; > + > + if (hwaddr_aton(blobmsg_data(tb[WNM_DISASSOC_ADDR]), addr)) > + return UBUS_STATUS_INVALID_ARGUMENT; > + > + if (tb[WNM_DISASSOC_DURATION]) > + duration = blobmsg_get_u32(tb[WNM_DISASSOC_DURATION]); > + > + abridged = !!(tb[WNM_DISASSOC_ABRIDGED] && > blobmsg_get_bool(tb[WNM_DISASSOC_ABRIDGED])); > + > + return hostapd_bss_tr_send(hapd, addr, true, abridged, duration, > duration, > + tb[WNM_DISASSOC_NEIGHBORS]); > +} > #endif > > #ifdef CONFIG_AIRTIME_POLICY > @@ -1454,6 +1525,7 @@ static const struct ubus_method bss_methods[] = { > UBUS_METHOD("rrm_beacon_req", hostapd_rrm_beacon_req, > beacon_req_policy), > #ifdef CONFIG_WNM_AP > UBUS_METHOD("wnm_disassoc_imminent", hostapd_wnm_disassoc_imminent, > wnm_disassoc_policy), > + UBUS_METHOD("bss_transition_request", hostapd_bss_transition_request, > bss_tr_policy), > #endif > }; > >
OpenPGP_signature
Description: OpenPGP digital signature
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel