A commonly used SFP+ form-factor XGS-PON ONT (WAS-110) reports 0x63 at
power on and then switches to 0x64 after booting up.
0x63 -> 9.9gbps
0x64 -> 10gbps
These are outside of the previous 0x66-0x69 range which prevented the
link from ever being brought up.
I recently brought a "Ztyuav Z-QWYT0402", the insides looked identical to the
existing supported "Hisource Hi-K0402WS". Both of them have the
"PCB-K0402-V3.0" silkscreen.
I flashed the vanilla image and it seems to work great.
I changed the documentation to be more inclusive of other devices (including
adding a picture of mine). I suspect more devices might fall into this
"PCB-K0402-V3.0" bucket, for example the "YuanLey YS25-0402" with
the vlan switch also looks suspiciously identical from the outside.
I also added some details I noticed while flashing mine:
teardown, flash padding, how the selector switch actually works.
- itoa16_html: add comment that the function is sufficient for VLAN
IDs (<=4094); generalization not needed.
- send_vlanlist: replace post-write bounds check with a pre-write
guard using worst-case entry size (138 bytes + 1 for closing
bracket). Old comment claimed ~45 bytes per entry, which only
held for short names. With a 117-char name (the actual bound from
CMD_BUF_SIZE) entries can reach 138 bytes, and the post-check
would not have prevented an overflow.
- Document the 0x02 check in sfr_data[0] as the VLAN table entry
valid flag.
The pattern /^vlan\s+\d{1,4}\b/ matched both VLAN membership entries
(vlan N <ports>) and management entries (vlan N mgmt), causing them
to overwrite each other in configuration[]. When saving, whichever
form came last in the cmd_log would dedupe the other out of the
final config — resulting in either lost membership or a stale mgmt
setting.
Split into two patterns using negative lookahead:
- /^vlan\s+\d{1,4}\s+mgmt$/ matches only mgmt entries
- /^vlan\s+\d{1,4}(?!\s+mgmt\b)/ matches everything else
Both dedup independently. Discovered via hardware test on 6XH-X
where 'vlan 44 mgmt' silently dropped 'vlan 44 management 2t 5u'
from saved config, locking out web UI on next boot.
Multiple related bugs in the Save-to-Flash path:
1. Multipart upload was missing the required filename argument,
causing the backend parser to fail. Added 'config.txt' to the
form.append call. This was likely the primary reason Save-to-Flash
was unreliable.
2. Web UI was not pausing its polling interval during flash write,
causing CPU contention and intermittent crashes. Added isSaving
lock and clearInterval before sendConfig.
3. conf_cmds whitelist was incomplete. Added: syslog, passwd, pvid,
ingress, port name, lag, laghash, isolate, stp, igmp, mtu, bw,
vlan N mgmt, vlan N d.
4. VLAN regex blocked named VLANs. New pattern allows optional name
(starts with letter, matching CLI parser semantics).
5. vlan N d (delete) was not persisted. parseConf now removes the
matching vlan N ... entry from configuration[] when seeing a
delete command, without storing the delete itself. Result: the
saved config describes the end state.
6. configuration[] was not cleared between flashSave invocations,
leading to stale entries from prior interactions.
7. conf_overwrite boundary fix: 'pvid 1' no longer matches 'pvid 10'
etc. Added trailing space in startsWith check.
8. All conf_cmds patterns now anchored with ^...$ for full-line
match. parseConf normalizes whitespace before testing.
9. Port range widened to \d{1,2} so ports 11+ are accepted.
Structural fixes (1, 2, 6, 7, 8) ported from mcaptur's closed PR #219;
remaining fixes (3, 4, 5, 9) and overall regex strategy are new.
The hardware bitmask format encodes both "untagged members" and
"non-members" in the upper 10 bits (per doc/vlan.md). The existing
fetchVLAN() correctly masks this with the membership bitmask before
display, but loadVlanTable() did not, causing non-member ports to
appear in the Untagged Ports column.
Tested on KeepLiNK KP-9000-6XH-X.
Below the configuration form, a new table lists all configured VLANs
with their port memberships: Member, Tagged, Untagged, and PVID
columns. Port ranges are formatted compactly (e.g. "1-2,5").
Port-to-bit mapping uses the existing physToLogPort[] array populated
by /status.json, so the table is consistent with the icon view in
fetchVLAN() and works on any supported machine.
Each row has a delete button that sends "vlan N d" via /cmd, with
a confirmation dialog. VLAN 1 cannot be deleted (no button shown).
Table and dropdown both refresh automatically after Update/Create
and after delete via a new refreshVlanViews() helper.
The N+1 request pattern (1x /vlanlist + Nx /vlan.json) keeps the
backend simple and avoids buffer overflow risks for systems with
many VLANs. For typical configurations (<50 VLANs), page load
remains under one second.
A new <select> element above the VLAN ID input lets users pick an
existing VLAN by name instead of typing the ID. Options are loaded
from /vlanlist on page load and re-loaded after successful
Update/Create operations.
Selection triggers the existing fetchVLAN() flow.
Falls back gracefully if /vlanlist returns an empty list or fails:
the dropdown is hidden and the existing ID input remains functional.
Returns a JSON array of all configured VLANs with their IDs and names,
e.g. [{"id":1,"name":""},{"id":20,"name":"IoT"}].
The endpoint iterates VLAN IDs 1..4094 and filters by the validity bit
in sfr_data[0] (0x02), following the same pattern as vlan_create() and
vlan_setup() in rtl837x_port.c.
Also adds a small itoa16_html() helper for emitting decimal numbers
up to 4 digits (analogous to the existing 8-bit itoa_html()), used
for VLAN IDs which can reach 4094. Response builder uses the existing
vlan_name() helper for the name lookup, consistent with send_vlan().
Buffer overflow is prevented by breaking out of the iteration loop at
TCP_OUTBUF_SIZE - 60.
This endpoint is the foundation for upcoming UI improvements
(VLAN selector dropdown and overview table).
1. While loop scanning VLAN name terminated only on ' ', not '\0'.
When the name is the last token in cmd_buffer, the loop reads past
the buffer into adjacent XRAM.
2. Entering 'vlan' without arguments causes parse_vlan() to read
cmd_words_b[1] which points to undefined memory, causing atoi_short()
to interpret residual bytes from previous commands as a VLAN ID.
Bug found and fix proposed by logicog during review of PR #232.
Co-Authored-By: logicog <logicog@users.noreply.github.com>
Adds CLI reference for the previously undocumented vlan <id> mgmt
command, including the disable case (vlan 0 mgmt), default state,
and a lockout warning.
Fixes#235
Previously, renaming a VLAN or deleting and recreating it with a
different name did not update the displayed name. The vlan_names[]
array is an append-only buffer where vlan_name() returns the first
matching entry, so stale entries kept winning.
This commit adds vlan_name_remove(), which locates an entry by
VLAN ID and removes it via array compaction. The function is called
in two places:
- parse_vlan() in cmd_parser.c, before appending a new name entry,
to remove any pre-existing entry for the same VLAN ID
- vlan_delete() in rtl837x_port.c, to clean up the name when a
VLAN is removed
The implementation reuses the existing vlan_name() lookup, scans for
the trailing space of the matched entry, then shifts remaining bytes
left. Locals are declared as static __xdata to avoid the SDCC
overlay segment limit on banked functions.
Tested on KeepLiNK KP-9000-6XH-X:
- vlan 99 AAA p1u; vlan 99 BBB -> name updated to BBB
- vlan 99 d; vlan 99 CCC p1u -> name correctly CCC, not stale AAA
Note: This fix addresses the runtime XMEM state. Persistence of
renamed VLAN names across reboot requires the user to download and
re-upload /config, as is the existing pattern for all configuration
changes in this firmware.
When checking for a new root, a root_bridge with the same priority as STP_I will never be adopted as cmpMAC always returns 0.
This PR fixes this bug by changing the comparison of MACs to what was intended
With content_type = "application/x-www-form-urlencoded", "+" means space.
This case was not handled.
Also refactor the code to make a loop to process the hex digits.
- machine.c/h: add MACHINE_FNS1200P with verified GPIO assignments for
both SFP ports, LED SET0 (amber 2.5G / green 1G-100M-10M) and SET1
(SFP all-speeds), led_mux from original firmware register dump, and
machine_custom_init() enabling LED_GLB_IO_EN bit 6
- doc/devices/FNS-1200P.md: device overview, port layout, serial
console (S1 three through-holes = UART0 115200 8N1 3.3V),
LED and SFP GPIO tables
- doc/devices/photos/FNS-1200P/: chassis front panel and PCB top photos
- doc/supported_devices.md: add FNS-1200P to the list
GPIO assignments and LED register values were cross-checked between
live GPIO observation (RTLPlayground gpio command) and an original
firmware register dump.
* Revise compiling section and add cautionary notes
Updated compiling instructions and added warnings about flashing procedures.
* Refactor caution messages in README.md
Updated caution messages to use new formatting for emphasis.
* Revise caution and reminder notes in README
Updated caution and reminder sections for clarity and consistency.
* Fix typos in README regarding firmware update
Corrected typo errors in the README.
* Add image for advanced settings
Add advanced_seetings.png
* Add advanced settings configuration details to README
Added advanced settings section with configuration instructions.
* Fix image source in README for advanced settings
Corrected the image source filename for advanced settings.
* Revise IP and port command descriptions in README
Updated command descriptions in README for clarity.
* Revise README.md for clarity and updated instructions
Updated sections in README.md for clarity and accuracy, including compiling requirements, installation instructions, and cautionary notes.
* Revise README for clarity and emphasis
Updated formatting and emphasized important notes in the README.
* Correct image file name and compilation output in README
Updated README to reflect changes in image file names and compilation output.