diff --git a/wifimngr.c b/wifimngr.c index cbe92518770b476fcab804bbf5730ac3f2b126b2..dbc01f018f107f62858f5809417906511912ae58 100644 --- a/wifimngr.c +++ b/wifimngr.c @@ -2185,6 +2185,78 @@ int wl_stop_cac(struct ubus_context *ctx, struct ubus_object *obj, return ret == 0 ? UBUS_STATUS_OK : UBUS_STATUS_UNKNOWN_ERROR; } +enum { + RADAR_CHANNEL, + RADAR_BANDWIDTH, + RADAR_TYPE, + RADAR_SUBBAND_MASK, + __RADAR_MAX, +}; + +static const struct blobmsg_policy wl_radar_policy[__RADAR_MAX] = { + [RADAR_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 }, + [RADAR_BANDWIDTH] = { .name = "bandwidth", .type = BLOBMSG_TYPE_INT32 }, + [RADAR_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_INT32 }, + [RADAR_SUBBAND_MASK] = { .name = "subband_mask", .type = BLOBMSG_TYPE_INT32 }, +}; + +int wl_simulate_radar(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct wifi_radar_args radar = { 0 }; + struct blob_attr *tb[__RADAR_MAX]; + const char *ifname; + int ret; + + ifname = ubus_radio_to_ifname(obj); + blobmsg_parse(wl_radar_policy, __RADAR_MAX, tb, blob_data(msg), blob_len(msg)); + + if (tb[RADAR_CHANNEL]) { + radar.channel = blobmsg_get_u32(tb[RADAR_CHANNEL]); + } + + if (tb[RADAR_BANDWIDTH]) { + int bandwidth; + + bandwidth = blobmsg_get_u32(tb[RADAR_BANDWIDTH]); + switch (bandwidth) { + case 20: + radar.bandwidth = BW20; + break; + case 40: + radar.bandwidth = BW40; + break; + case 80: + radar.bandwidth = BW80; + break; + case 160: + radar.bandwidth = BW160; + break; + default: + radar.bandwidth = BW_UNKNOWN; + } + } + + if (tb[RADAR_TYPE]) { + radar.type = blobmsg_get_u32(tb[RADAR_TYPE]); + } + + if (tb[RADAR_SUBBAND_MASK]) { + /* subband mask can be from range 0 - 0x0FF + * here is the rule: + * bit: 3 2 1 0 + * low freq | 20MHz | 20MHz | 20MHz| 20MHz | high freq + * | 80MHz | + */ + radar.subband_mask = blobmsg_get_u32(tb[RADAR_SUBBAND_MASK]); + } + + ret = wifi_simulate_radar(ifname, &radar); + + return ret == 0 ? UBUS_STATUS_OK : UBUS_STATUS_UNKNOWN_ERROR; +} + static void uci_add_option(struct uci_context *ctx, struct uci_package *p, struct uci_section *s, const char *option, void *value, bool is_list) @@ -4437,11 +4509,14 @@ static int add_radio_methods(struct ubus_object *radio_obj, { struct ubus_method *radio_methods; int n_methods = 0; + enum wifi_band band; radio_methods = calloc(MAX_RADIO_METHODS, sizeof(struct ubus_method)); if (!radio_methods) return -ENOMEM; + wifi_get_oper_band(radioname, &band); + UBUS_METHOD_ADD(radio_methods, n_methods, UBUS_METHOD_NOARG("status", wl_radio_status)); @@ -4496,6 +4571,12 @@ static int add_radio_methods(struct ubus_object *radio_obj, UBUS_METHOD_NOARG("opclass_preferences", wl_opclass_preferences)); } + if (libwifi_supports(radioname, "wifi_simulate_radar") && + (band == BAND_5 || band == BAND_DUAL || band == BAND_UNKNOWN)) { + UBUS_METHOD_ADD(radio_methods, n_methods, + UBUS_METHOD("simulate_radar", wl_simulate_radar, wl_radar_policy)); + } + radio_obj->methods = radio_methods; radio_obj->n_methods = n_methods;