From 167232a4fdb23d6e28b4a822889b40ae72ea65c1 Mon Sep 17 00:00:00 2001 From: Tanya Singh Date: Tue, 21 Jul 2026 17:13:35 +0800 Subject: [PATCH] radio: add puncture-threshold for preamble puncturing Add a new 'puncture-threshold' integer property (0-100, default 0) to the radio schema to control preamble puncturing during auto channel selection. A value of 0 disables puncturing so ACS will not puncture any channel. The renderer emits wireless..ru_punct_acs_threshold via a new match_puncture_threshold() helper that enforces the supported conditions, falling back to 0 with a warning when: - the band is 2G or HaLow - the channel is not in 'auto' mode - the channel-width is below 80MHz - the channel-mode is not EHT Fixes: WIFI-15612 Signed-off-by: Tanya Singh --- renderer/templates/radio.uc | 28 ++++++++++++++++++++++++++++ schema/radio.yml | 13 +++++++++++++ schemareader.uc | 23 +++++++++++++++++++++++ ucentral.schema.full.json | 7 +++++++ ucentral.schema.json | 6 ++++++ ucentral.schema.pretty.json | 7 +++++++ 6 files changed, 84 insertions(+) diff --git a/renderer/templates/radio.uc b/renderer/templates/radio.uc index c770db85..241d9579 100644 --- a/renderer/templates/radio.uc +++ b/renderer/templates/radio.uc @@ -160,6 +160,33 @@ return modes[require_mode] || ''; } + function match_puncture_threshold(phy, radio) { + if (!radio.puncture_threshold) + return 0; + + if (radio.band == "2G" || radio.band == "HaLow") { + warn("puncture-threshold is not supported on the %s band, ignoring", radio.band); + return 0; + } + + if (radio.channel_mode != "EHT") { + warn("puncture-threshold requires channel-mode EHT, ignoring for band %s", radio.band); + return 0; + } + + if (match_channel(phy, radio) != 0) { + warn("puncture-threshold is only supported with 'auto' channel mode, ignoring for band %s", radio.band); + return 0; + } + + if (radio.channel_width < 80) { + warn("puncture-threshold is not supported with channel-width below 80MHz, ignoring for band %s", radio.band); + return 0; + } + + return radio.puncture_threshold; + } + if (restrict.dfs && radio.allow_dfs && radio.band == "5G") { warn('DFS is restricted.'); radio.allow_dfs = false; @@ -234,6 +261,7 @@ set wireless.{{ phy.section }}.maxassoc={{ radio.maximum_clients }} set wireless.{{ phy.section }}.maxassoc_ignore_probe={{ b(radio.maximum_clients_ignore_probe) }} set wireless.{{ phy.section }}.reconf={{ b(reconf) }} set wireless.{{ phy.section }}.acs_exclude_dfs={{ b(!radio.allow_dfs) }} +set wireless.{{ phy.section }}.ru_punct_acs_threshold={{ match_puncture_threshold(phy, radio) }} {% for (let channel in radio.valid_channels): %} {% if (!(channel in phy.channels)) continue %} {% if (!radio.allow_dfs && channel in phy.dfs_channels) continue %} diff --git a/schema/radio.yml b/schema/radio.yml index 00efa946..feec3250 100644 --- a/schema/radio.yml +++ b/schema/radio.yml @@ -48,6 +48,19 @@ properties: Exclude non-psc when doing auto channel selection on 6GHz type: boolean default: false + puncture-threshold: + description: + Enables preamble puncturing during auto channel selection (ACS). The value is + an RSSI-like threshold that indicates how aggressively the ACS algorithm may + puncture individual sub-channels of the operating channel. A value of 0 disables + preamble puncturing, meaning the ACS algorithm will not puncture any channel. + Puncturing can only be enabled when the radio is using the 'auto' channel mode, + requires a channel-mode of EHT, is not supported on the 2G or HaLow bands, + and requires a channel-width of at least 80MHz. + type: integer + maximum: 100 + minimum: 0 + default: 0 country: description: Specifies the country code, affects the available channels and diff --git a/schemareader.uc b/schemareader.uc index 6f2fd698..2b988ae7 100644 --- a/schemareader.uc +++ b/schemareader.uc @@ -1204,6 +1204,29 @@ function instantiateRadio(location, value, errors) { obj.acs_exclude_6ghz_non_psc = false; } + function parsePunctureThreshold(location, value, errors) { + if (type(value) in [ "int", "double" ]) { + if (value > 100) + push(errors, [ location, "must be lower than or equal to 100" ]); + + if (value < 0) + push(errors, [ location, "must be bigger than or equal to 0" ]); + + } + + if (type(value) != "int") + push(errors, [ location, "must be of type integer" ]); + + return value; + } + + if (exists(value, "puncture-threshold")) { + obj.puncture_threshold = parsePunctureThreshold(location + "/puncture-threshold", value["puncture-threshold"], errors); + } + else { + obj.puncture_threshold = 0; + } + function parseCountry(location, value, errors) { if (type(value) == "string") { if (length(value) > 2) diff --git a/ucentral.schema.full.json b/ucentral.schema.full.json index 404d6239..62ec3e34 100644 --- a/ucentral.schema.full.json +++ b/ucentral.schema.full.json @@ -612,6 +612,13 @@ "type": "boolean", "default": false }, + "puncture-threshold": { + "description": "Enables preamble puncturing during auto channel selection (ACS). The value is an RSSI-like threshold that indicates how aggressively the ACS algorithm may puncture individual sub-channels of the operating channel. A value of 0 disables preamble puncturing, meaning the ACS algorithm will not puncture any channel. Puncturing can only be enabled when the radio is using the 'auto' channel mode, requires a channel-mode of EHT, is not supported on the 2G or HaLow bands, and requires a channel-width of at least 80MHz.", + "type": "integer", + "maximum": 100, + "minimum": 0, + "default": 0 + }, "country": { "description": "Specifies the country code, affects the available channels and transmission powers.", "type": "string", diff --git a/ucentral.schema.json b/ucentral.schema.json index 9c138d53..12109b26 100644 --- a/ucentral.schema.json +++ b/ucentral.schema.json @@ -526,6 +526,12 @@ "type": "boolean", "default": false }, + "puncture-threshold": { + "type": "integer", + "maximum": 100, + "minimum": 0, + "default": 0 + }, "country": { "type": "string", "maxLength": 2, diff --git a/ucentral.schema.pretty.json b/ucentral.schema.pretty.json index 3f2a3ce3..cc534a8f 100644 --- a/ucentral.schema.pretty.json +++ b/ucentral.schema.pretty.json @@ -590,6 +590,13 @@ "type": "boolean", "default": false }, + "puncture-threshold": { + "description": "Enables preamble puncturing during auto channel selection (ACS). The value is an RSSI-like threshold that indicates how aggressively the ACS algorithm may puncture individual sub-channels of the operating channel. A value of 0 disables preamble puncturing, meaning the ACS algorithm will not puncture any channel. Puncturing can only be enabled when the radio is using the 'auto' channel mode, requires a channel-mode of EHT, is not supported on the 2G or HaLow bands, and requires a channel-width of at least 80MHz.", + "type": "integer", + "maximum": 100, + "minimum": 0, + "default": 0 + }, "country": { "description": "Specifies the country code, affects the available channels and transmission powers.", "type": "string",