What happened?
A BSSID entered in WiFi Setup → BSSID (optional) with the usual : or -
separators is silently parsed into a wrong value. No error is shown, the field
appears accepted, and the effect is that BSSID pinning simply never matches —
findWiFi() falls back to picking by RSSI as though nothing had been set.
fillStr2MAC() (wled00/network.cpp:339) parses the field with
strtoull(str, nullptr, 16), which stops at the first non-hex character:
void fillStr2MAC(uint8_t *mac, const char *str) {
for (int i = 0; i < 6; i++) *mac++ = 0;
if (!str) return;
uint64_t MAC = strtoull(str, nullptr, 16);
for (int i = 0; i < 6; i++) { *--mac = MAC & 0xFF; MAC >>= 8; }
}
The input is maxlength="12" (settings_wifi.htm:136), so a colon-separated
MAC is also truncated to 12 characters before it ever reaches the parser. The
two combine: 9E:2A:6F:44:27:7A becomes the field value 9E:2A:6F:44:, which
parses as 0x9E, and is stored as 00:00:00:00:00:9E.
Compiling fillStr2MAC() unmodified and feeding it what the form would submit:
target BSSID 9E:2A:6F:44:27:7A
typed with colons -> field 9E:2A:6F:44: -> 00:00:00:00:00:9E
typed with dashes -> field 9E-2A-6F-44- -> 00:00:00:00:00:9E
lowercase, colons -> field 9e:2a:6f:44: -> 00:00:00:00:00:9E
no separators (ok) -> field 9E2A6F44277A -> 9E:2A:6F:44:27:7A
Only the bare-hex form works, and nothing on the page says so — the label is
just "BSSID (optional):", with no placeholder, no pattern, and no hint that
separators are disallowed. Every other place a MAC is shown to the user
(including the network scanner in the same dialog) displays it with colons.
This affects both entry paths, neither of which strips separators:
- the settings form —
wled00/set.cpp:54
POST /json/cfg — wled00/cfg.cpp:108
To Reproduce Bug
- WiFi Setup → enter a valid SSID.
- In BSSID (optional) type a real BSSID the normal way, e.g.
9E:2A:6F:44:27:7A. Note the field stops accepting input after 12
characters, leaving 9E:2A:6F:44:.
- Save.
- Read it back with
GET /json/cfg → nw.ins[0].bssid is "9e2a6f44"-ish
rather than what was intended, and the pin has no effect on AP selection.
Expected Behavior
Either of:
- Accept the separated form. Stripping
: and - before parsing would make
the field behave the way the displayed MACs elsewhere in the UI lead you to
expect; or
- Reject it visibly — a
pattern/validation message, so a wrong value cannot
be saved silently.
Ideally also a placeholder="9E2A6F44277A" on the input, since the required
format is currently undiscoverable.
Worth noting: settings_wifi.htm:72 already contains
networks[i].bssid.replaceAll(':','') in a commented-out fragment of the
scanner's option text, so the need to strip separators was anticipated
somewhere along the way.
Install Method
Self-compiled
What version of WLED?
17.0.0-devV5, built from main at d9b9a84. The code path is unchanged in
released versions.
Which microcontroller/board are you seeing the problem on?
ESP32
Anything else?
Low severity, but the failure is entirely silent, and the symptom it produces —
"BSSID pinning doesn't work" — points away from the actual cause. Someone
debugging why their device still roams has no reason to suspect the field they
filled in correctly-looking.
Happy to open a PR for whichever of the two behaviours you'd prefer; stripping
separators in fillStr2MAC() plus raising the input maxlength would be the
smaller change and keeps both the bare and separated forms working.
What happened?
A BSSID entered in WiFi Setup → BSSID (optional) with the usual
:or-separators is silently parsed into a wrong value. No error is shown, the field
appears accepted, and the effect is that BSSID pinning simply never matches —
findWiFi()falls back to picking by RSSI as though nothing had been set.fillStr2MAC()(wled00/network.cpp:339) parses the field withstrtoull(str, nullptr, 16), which stops at the first non-hex character:The input is
maxlength="12"(settings_wifi.htm:136), so a colon-separatedMAC is also truncated to 12 characters before it ever reaches the parser. The
two combine:
9E:2A:6F:44:27:7Abecomes the field value9E:2A:6F:44:, whichparses as
0x9E, and is stored as00:00:00:00:00:9E.Compiling
fillStr2MAC()unmodified and feeding it what the form would submit:Only the bare-hex form works, and nothing on the page says so — the label is
just "BSSID (optional):", with no placeholder, no
pattern, and no hint thatseparators are disallowed. Every other place a MAC is shown to the user
(including the network scanner in the same dialog) displays it with colons.
This affects both entry paths, neither of which strips separators:
wled00/set.cpp:54POST /json/cfg—wled00/cfg.cpp:108To Reproduce Bug
9E:2A:6F:44:27:7A. Note the field stops accepting input after 12characters, leaving
9E:2A:6F:44:.GET /json/cfg→nw.ins[0].bssidis"9e2a6f44"-ishrather than what was intended, and the pin has no effect on AP selection.
Expected Behavior
Either of:
:and-before parsing would makethe field behave the way the displayed MACs elsewhere in the UI lead you to
expect; or
pattern/validation message, so a wrong value cannotbe saved silently.
Ideally also a
placeholder="9E2A6F44277A"on the input, since the requiredformat is currently undiscoverable.
Worth noting:
settings_wifi.htm:72already containsnetworks[i].bssid.replaceAll(':','')in a commented-out fragment of thescanner's option text, so the need to strip separators was anticipated
somewhere along the way.
Install Method
Self-compiled
What version of WLED?
17.0.0-devV5, built frommainatd9b9a84. The code path is unchanged inreleased versions.
Which microcontroller/board are you seeing the problem on?
ESP32
Anything else?
Low severity, but the failure is entirely silent, and the symptom it produces —
"BSSID pinning doesn't work" — points away from the actual cause. Someone
debugging why their device still roams has no reason to suspect the field they
filled in correctly-looking.
Happy to open a PR for whichever of the two behaviours you'd prefer; stripping
separators in
fillStr2MAC()plus raising the inputmaxlengthwould be thesmaller change and keeps both the bare and separated forms working.