mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
Compare commits
49
Commits
889c94404c
...
7b4d0d55d2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b4d0d55d2 | ||
|
|
fe1d4119d0 | ||
|
|
5c6a82d50f | ||
|
|
26c420d26a | ||
|
|
eb394af95f | ||
|
|
4a4caeffd7 | ||
|
|
391360f517 | ||
|
|
ed8e4b1a56 | ||
|
|
78f28488c1 | ||
|
|
e1c79ec4cd | ||
|
|
a7db0ca8b6 | ||
|
|
70f59b64f5 | ||
|
|
f0cbaba7b1 | ||
|
|
a18c334139 | ||
|
|
337b171ac4 | ||
|
|
53eb3f5486 | ||
|
|
241edfdbda | ||
|
|
714c9eb343 | ||
|
|
f2c89fd75b | ||
|
|
ca2f1d101d | ||
|
|
9cc859ad30 | ||
|
|
0181276ec6 | ||
|
|
905e588071 | ||
|
|
bb16302a80 | ||
|
|
50fda40fd9 | ||
|
|
9c65039bab | ||
|
|
7e0bc93b55 | ||
|
|
e1e1292ab0 | ||
|
|
975caaff02 | ||
|
|
cffe4793b1 | ||
|
|
9ed1e89c8b | ||
|
|
ba2f759df3 | ||
|
|
884a1ac016 | ||
|
|
51ed063dcb | ||
|
|
0da6318777 | ||
|
|
d13a5d125d | ||
|
|
7b0a07efaa | ||
|
|
3deee14f94 | ||
|
|
827d3b389c | ||
|
|
ef224ec8f4 | ||
|
|
a1998c70d7 | ||
|
|
196d22d7c3 | ||
|
|
680a40dab5 | ||
|
|
97b15f4022 | ||
|
|
d5ccd38dd3 | ||
|
|
6bae5c5c90 | ||
|
|
c2980e42d8 | ||
|
|
875933b9f9 | ||
|
|
d0374541c5 |
No files matched your search
@@ -3,6 +3,7 @@
|
|||||||
.gitattributes
|
.gitattributes
|
||||||
.github/
|
.github/
|
||||||
output/
|
output/
|
||||||
|
toolchain/
|
||||||
installer/output/
|
installer/output/
|
||||||
*.bin
|
*.bin
|
||||||
html_data.c
|
html_data.c
|
||||||
|
|||||||
@@ -29,7 +29,12 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
apt update
|
apt update
|
||||||
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev zlib1g-dev -y
|
apt install make gcc g++ bison flex libboost-dev patch bzip2 curl ca-certificates xxd python-is-python3 libjson-c-dev zlib1g-dev -y
|
||||||
|
- name: Cache the patched SDCC
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: branch/toolchain
|
||||||
|
key: sdcc-${{ hashFiles('branch/sdcc/*') }}
|
||||||
- name: Run the host-side unit tests
|
- name: Run the host-side unit tests
|
||||||
run: cd branch && make -C test
|
run: cd branch && make -C test
|
||||||
- name: Check that every machine definition can be compiled
|
- name: Check that every machine definition can be compiled
|
||||||
@@ -41,7 +46,10 @@ jobs:
|
|||||||
- name: Make project with the health instrumentation
|
- name: Make project with the health instrumentation
|
||||||
run: cd branch && make clean && make CI=1 MACHINE="KP_9000_6XHML_X2" HEALTH=1
|
run: cd branch && make clean && make CI=1 MACHINE="KP_9000_6XHML_X2" HEALTH=1
|
||||||
- name: Make main
|
- name: Make main
|
||||||
run: cd main && make CI=1 MACHINE="KP_9000_6XHML_X2" && cp output/KP_9000_6XHML_X2/rtlplayground.map /tmp/main.map
|
run: |
|
||||||
|
ln -s ../branch/toolchain main/toolchain
|
||||||
|
PATH="$(echo "$PWD"/branch/toolchain/sdcc-*/bin):$PATH"
|
||||||
|
cd main && make CI=1 MACHINE="KP_9000_6XHML_X2" && cp output/KP_9000_6XHML_X2/rtlplayground.map /tmp/main.map
|
||||||
- name: Calculate bank growth
|
- name: Calculate bank growth
|
||||||
run: |
|
run: |
|
||||||
sed -rn 's/^([XCD]SEG|(BANK[0-9])).*=\s+([0-9]+)\. bytes.*$/MAIN_\1=\3/p' /tmp/main.map | sort -u >> "$GITHUB_ENV"
|
sed -rn 's/^([XCD]SEG|(BANK[0-9])).*=\s+([0-9]+)\. bytes.*$/MAIN_\1=\3/p' /tmp/main.map | sort -u >> "$GITHUB_ENV"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
.idea/
|
.idea/
|
||||||
output/
|
output/
|
||||||
output-main/
|
output-main/
|
||||||
|
toolchain/
|
||||||
html_data.c
|
html_data.c
|
||||||
html_data.h
|
html_data.h
|
||||||
version.h
|
version.h
|
||||||
|
|||||||
@@ -25,7 +25,16 @@
|
|||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
- Time
|
||||||
|
- `rtl8372_init()` sets SDS 0 to SGMII as the stock firmware does. The masks were 0, so on RTL8372
|
||||||
|
boards without 10G ports both SerDes stayed off, and with SDS 0 off `RTL837X_REG_SEC_COUNTER`
|
||||||
|
does not hold a written value: NTP never retried after a failed first attempt at boot and
|
||||||
|
froze the clock after a sync.
|
||||||
|
|
||||||
- Web UI
|
- Web UI
|
||||||
|
- Firefox no longer fills a saved login into the new admin password fields. It also put the
|
||||||
|
user name into the NTP poll interval, which marked the Time card as edited, so it kept its
|
||||||
|
defaults (NTP off, no server, UTC-12:00) instead of the switch's settings.
|
||||||
- Accept firmware uploads regardless of the file part's MIME type, including
|
- Accept firmware uploads regardless of the file part's MIME type, including
|
||||||
`application/macbinary` sent by Chrome on macOS for `.bin` files.
|
`application/macbinary` sent by Chrome on macOS for `.bin` files.
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -3,7 +3,14 @@ FROM debian:13-slim
|
|||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
make \
|
make \
|
||||||
gcc \
|
gcc \
|
||||||
sdcc \
|
g++ \
|
||||||
|
bison \
|
||||||
|
flex \
|
||||||
|
libboost-dev \
|
||||||
|
patch \
|
||||||
|
bzip2 \
|
||||||
|
curl \
|
||||||
|
ca-certificates \
|
||||||
xxd \
|
xxd \
|
||||||
python3 \
|
python3 \
|
||||||
libjson-c-dev \
|
libjson-c-dev \
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ DEFAULT_CONFIG_LOCATION = 454656
|
|||||||
CONFIG_LOCATION = 458752
|
CONFIG_LOCATION = 458752
|
||||||
HTML_LOCATION = 262144
|
HTML_LOCATION = 262144
|
||||||
|
|
||||||
|
SDCC_PREFIX = toolchain/sdcc-$(shell cat sdcc/* | cksum | cut -d' ' -f1)
|
||||||
ifeq ($(origin CC),default)
|
ifeq ($(origin CC),default)
|
||||||
CC = sdcc
|
SDCC = $(SDCC_PREFIX)/bin/sdcc
|
||||||
|
CC = $(SDCC)
|
||||||
|
ASM = $(SDCC_PREFIX)/bin/sdas8051
|
||||||
endif
|
endif
|
||||||
CC_FLAGS = -mmcs51 -I. -Imachine -Ihttpd -Iuip
|
CC_FLAGS = -mmcs51 -I. -Imachine -Ihttpd -Iuip
|
||||||
ASM ?= sdas8051
|
ASM ?= sdas8051
|
||||||
@@ -72,7 +75,7 @@ all: create_build_dir $(VERSION_HEADER) $(MACHINE_SRC) $(SUBDIRS) $(BUILDDIR)/rt
|
|||||||
bank_size:
|
bank_size:
|
||||||
tools/bank_occupancy.sh "$(MACHINE)"
|
tools/bank_occupancy.sh "$(MACHINE)"
|
||||||
|
|
||||||
create_build_dir:
|
create_build_dir: $(SDCC)
|
||||||
mkdir -p "$(BUILDDIR)"
|
mkdir -p "$(BUILDDIR)"
|
||||||
mkdir -p "$(BUILDDIR)/uip"
|
mkdir -p "$(BUILDDIR)/uip"
|
||||||
mkdir -p "$(BUILDDIR)/httpd"
|
mkdir -p "$(BUILDDIR)/httpd"
|
||||||
@@ -102,6 +105,7 @@ SRCS = \
|
|||||||
sfp.c \
|
sfp.c \
|
||||||
dns.c \
|
dns.c \
|
||||||
dns_cli.c \
|
dns_cli.c \
|
||||||
|
sessions.c \
|
||||||
ntp.c \
|
ntp.c \
|
||||||
ntp_cli.c \
|
ntp_cli.c \
|
||||||
syslog.c \
|
syslog.c \
|
||||||
@@ -145,13 +149,23 @@ HTML := $(shell find html -name '*.js' -or -name '*.html' -or -name '*.svg' -or
|
|||||||
# The raw html/ sources stay untouched for development; the minified
|
# The raw html/ sources stay untouched for development; the minified
|
||||||
# copy is a build artifact under output/.
|
# copy is a build artifact under output/.
|
||||||
HTML_MIN := $(BUILDDIR)/html_min
|
HTML_MIN := $(BUILDDIR)/html_min
|
||||||
|
HTML_MIN_LIST := $(BUILDDIR)/html_min.list
|
||||||
|
HTML_MIN_STAMP := $(BUILDDIR)/html_min.stamp
|
||||||
.PHONY: html_min
|
.PHONY: html_min
|
||||||
html_min: $(HTML)
|
html_min: $(HTML_MIN_STAMP)
|
||||||
|
|
||||||
|
$(HTML_MIN_LIST): FORCE
|
||||||
|
@mkdir -p $(BUILDDIR)
|
||||||
|
@echo $(sort $(HTML)) > $@.tmp
|
||||||
|
@cmp -s $@.tmp $@ && rm -f $@.tmp || mv $@.tmp $@
|
||||||
|
|
||||||
|
$(HTML_MIN_STAMP): $(HTML) $(HTML_MIN_LIST) tools/minify.py $(if $(wildcard $(HTML_MIN)),,FORCE)
|
||||||
rm -rf $(HTML_MIN)
|
rm -rf $(HTML_MIN)
|
||||||
mkdir -p $(HTML_MIN)
|
mkdir -p $(HTML_MIN)
|
||||||
@for f in $(HTML); do python3 tools/minify.py $$f $(HTML_MIN)/$$(basename $$f) || exit 1; done
|
@for f in $(HTML); do python3 tools/minify.py $$f $(HTML_MIN)/$$(basename $$f) || exit 1; done
|
||||||
|
@touch $@
|
||||||
|
|
||||||
html_data.c html_data.h &: $(HTML) | tools html_min
|
html_data.c html_data.h &: $(HTML_MIN_STAMP) | tools
|
||||||
tools/$(BUILDDIR)/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -z -d $(HTML_MIN) -p html_data
|
tools/$(BUILDDIR)/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -z -d $(HTML_MIN) -p html_data
|
||||||
|
|
||||||
$(VERSION_HEADER): FORCE
|
$(VERSION_HEADER): FORCE
|
||||||
@@ -169,12 +183,18 @@ $(SUBDIRS):
|
|||||||
$(MAKE) -C $@ BUILDDIR=$(BUILDDIR)
|
$(MAKE) -C $@ BUILDDIR=$(BUILDDIR)
|
||||||
|
|
||||||
clean: $(SUBDIRSCLEAN)
|
clean: $(SUBDIRSCLEAN)
|
||||||
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
-rm -f html_data.c html_data.h $(VERSION_HEADER) $(HTML_MIN_LIST) $(HTML_MIN_STAMP)
|
||||||
-if [ -d $(BUILDDIR) ]; then find $(BUILDDIR) -type f ! -name "*.bin" -delete; fi
|
-if [ -d $(BUILDDIR) ]; then find $(BUILDDIR) -type f ! -name "*.bin" -delete; fi
|
||||||
|
|
||||||
distclean: $(SUBDIRSCLEAN)
|
distclean: $(SUBDIRSCLEAN)
|
||||||
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
-rm -f html_data.c html_data.h $(VERSION_HEADER) $(HTML_MIN_LIST) $(HTML_MIN_STAMP)
|
||||||
-rm -rf $(BUILDDIR)
|
-rm -rf $(BUILDDIR)
|
||||||
|
-rm -rf toolchain
|
||||||
|
|
||||||
|
ifneq ($(SDCC),)
|
||||||
|
$(SDCC):
|
||||||
|
sh sdcc/build.sh $(abspath $(SDCC_PREFIX))
|
||||||
|
endif
|
||||||
|
|
||||||
$(SUBDIRSCLEAN):
|
$(SUBDIRSCLEAN):
|
||||||
$(MAKE) -C $(@:clean=) clean
|
$(MAKE) -C $(@:clean=) clean
|
||||||
@@ -214,16 +234,18 @@ $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.i
|
|||||||
.PHONY: clean distclean all $(SUBDIRS) $(SUBDIRSCLEAN) create_build_dir
|
.PHONY: clean distclean all $(SUBDIRS) $(SUBDIRSCLEAN) create_build_dir
|
||||||
|
|
||||||
# Every machine/ definition is compiled, so a machine added to machine/ is
|
# Every machine/ definition is compiled, so a machine added to machine/ is
|
||||||
# covered without registering it anywhere. The _init.c files are excluded here:
|
# covered without registering it anywhere. A board only counts once both its
|
||||||
# they are the boot hooks, compiled separately below (the board's own if it
|
# <machine>.c and its <machine>.h are present: the header is what the rest of
|
||||||
# exists, otherwise default_machine_init.c). The machine-specific defines are
|
# the build includes, so a .c without one is an incomplete board. The _init.c
|
||||||
# filtered out of $(CC_FLAGS) and supplied per iteration instead, so this also
|
# files are excluded here: they are the boot hooks, compiled separately below
|
||||||
# works as "make machine_check MACHINE=...".
|
# (the board's own if it exists, otherwise default_machine_init.c). The
|
||||||
MACHINE_DEFS := $(sort $(patsubst machine/%.c,%,$(filter-out machine/%_init.c,$(wildcard machine/*.c))))
|
# machine-specific defines are filtered out of $(CC_FLAGS) and supplied per
|
||||||
|
# iteration instead, so this also works as "make machine_check MACHINE=...".
|
||||||
|
MACHINE_DEFS := $(sort $(filter $(patsubst machine/%.h,%,$(wildcard machine/*.h)),$(patsubst machine/%.c,%,$(filter-out machine/%_init.c,$(wildcard machine/*.c)))))
|
||||||
MACHINE_LESS_CC_FLAGS = $(filter-out -DMACHINE_%,$(CC_FLAGS))
|
MACHINE_LESS_CC_FLAGS = $(filter-out -DMACHINE_%,$(CC_FLAGS))
|
||||||
|
|
||||||
.PHONY: machine_check
|
.PHONY: machine_check
|
||||||
machine_check:
|
machine_check: $(SDCC)
|
||||||
@mkdir -p $(BUILDDIR)/tmp
|
@mkdir -p $(BUILDDIR)/tmp
|
||||||
@set -eo pipefail; \
|
@set -eo pipefail; \
|
||||||
for MACHINE in $(MACHINE_DEFS); \
|
for MACHINE in $(MACHINE_DEFS); \
|
||||||
|
|||||||
@@ -56,12 +56,19 @@ device simulator is provided, which runs entirely under Linux as a local webserv
|
|||||||
|
|
||||||
## (0) Compiling Requirements
|
## (0) Compiling Requirements
|
||||||
|
|
||||||
Install the following particular build requisites (Debian 12/13), note that Ubuntu 24.04
|
Install the following particular build requisites (Debian 12/13):
|
||||||
still has an older version of sdcc, but you will need sdcc version 4.5 for the code to compile:
|
|
||||||
```
|
```
|
||||||
sudo apt install make gcc sdcc xxd python-is-python3 libjson-c-dev zlib1g-dev
|
sudo apt install make gcc g++ bison flex libboost-dev patch bzip2 curl xxd python-is-python3 libjson-c-dev zlib1g-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The first `make` downloads SDCC 4.6.0, applies the fixes in `sdcc/` and builds it into
|
||||||
|
`toolchain/`, which takes a few minutes. Later builds reuse it. The released SDCC 4.5.0
|
||||||
|
and 4.6.0 miscompile parts of this code, see [SDCC bug #4153](https://sourceforge.net/p/sdcc/bugs/4153/)
|
||||||
|
and [#4154](https://sourceforge.net/p/sdcc/bugs/4154/); both fixes are in SDCC trunk since
|
||||||
|
r17039. The third patch is for [#4070](https://sourceforge.net/p/sdcc/bugs/4070/), where the
|
||||||
|
assembler drops the top byte of a `__sfr32` address list; it is proposed upstream and lets
|
||||||
|
`SFR_DATA_U32` be used again. To use an SDCC you installed yourself instead, run `make CC=sdcc ...`.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>If using Docker (click to expand)</summary>
|
<summary>If using Docker (click to expand)</summary>
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -24,6 +24,7 @@
|
|||||||
#include "sfp.h"
|
#include "sfp.h"
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "syslog.h"
|
#include "syslog.h"
|
||||||
|
#include "sessions.h"
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
#include "ntp.h"
|
#include "ntp.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
@@ -849,7 +850,7 @@ void parse_mirror(void)
|
|||||||
print_string("NOT Enabled: ");
|
print_string("NOT Enabled: ");
|
||||||
}
|
}
|
||||||
print_string("Mirroring port: ");
|
print_string("Mirroring port: ");
|
||||||
print_phys_port(mirroring_port);
|
print_phys_port(mPort >> 1);
|
||||||
reg_read_m(RTL837x_MIRROR_CONF);
|
reg_read_m(RTL837x_MIRROR_CONF);
|
||||||
uint16_t m = sfr_data[0];
|
uint16_t m = sfr_data[0];
|
||||||
m = (m << 8) | sfr_data[1];
|
m = (m << 8) | sfr_data[1];
|
||||||
@@ -1479,6 +1480,9 @@ void parse_passwd(void)
|
|||||||
passwd[j++] = c;
|
passwd[j++] = c;
|
||||||
} while (c != NUL && j < 20);
|
} while (c != NUL && j < 20);
|
||||||
passwd[j] = NUL;
|
passwd[j] = NUL;
|
||||||
|
/* Logins made with the old password end here. With one session the next
|
||||||
|
* login pushed a leftover one out; with several it would stay valid. */
|
||||||
|
session_init();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cmd_error("Missing password\n");
|
cmd_error("Missing password\n");
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
# MokerLink POE-2G080110GS
|
# MokerLink POE-2G080110GS
|
||||||
|
|
||||||
The `POE-2G080110GS` is an unmanaged 8x2.5G RJ45 and 1xSFP+ PoE switch sold by Mokerlink. There is also a `POE-2G080110GSM` managed version of the switch which may be similar but this has not been verified on actual hardware.
|
The `POE-2G080110GS` is an unmanaged 8x2.5G RJ45 and 1xSFP+ PoE switch sold by Mokerlink. There is also a `POE-2G080110GSM` managed version of the switch which may be similar but this has not been verified on actual hardware.
|
||||||
|
The`KP-9000-9XHP-X` is the KeepLink rebrand for same product.
|
||||||
|
|
||||||
## Brands
|
## Brands
|
||||||
| Brand | Type |Managed| PCB | Flash | Chip RTL |
|
| Brand | Type |Managed| PCB | Flash | Chip RTL |
|
||||||
|--------|------------------|-------|------------------|-----------------|---------------|
|
|--------|------------------|-------|------------------|-----------------|---------------|
|
||||||
| Mokerlink | POE-2G080110GS | No | 2M-PCB51-ML-V1.1 | 4MB (W25Q32JV) | 8373N + 8224N |
|
| Mokerlink | POE-2G080110GS | No | 2M-PCB51-ML-V1.1 | 4MB (W25Q32JV) | 8373N + 8224N |
|
||||||
|
| KeepLink | KP-9000-9XHP-X | No | 2M-PCB51-ML-V1.1 | 4MB (W25Q32JV) | 8373N + 8224N |
|
||||||
|
|
||||||
## Hardware overview
|
## Hardware overview
|
||||||
Front
|
Front
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
# PCB-AFGW SWTG218ANS V2.0.2
|
||||||
|
|
||||||
|
RTL8373-based 8×2.5G PoE + 1×10G SFP+ web-managed switch, sold as the
|
||||||
|
**RealHD PSW8-25MG**.
|
||||||
|
|
||||||
|
### Label specifications
|
||||||
|
|
||||||
|
- **Manufacturer**: RealHD
|
||||||
|
- **Model**: PSW8-25MG
|
||||||
|
- **PCB marking**: `PCB-AFGW SWTG218ANS_V2.0.2` (silkscreened as `PCB-AFGW SWTG218ANS_V2.0.2_23308`)
|
||||||
|
- **Ports**:
|
||||||
|
- 8 × RJ45: 10/100/1000/2500 Mbps with PoE
|
||||||
|
- 1 × SFP+: 1G / 2.5G / 10G (front panel marking `9(10G)`)
|
||||||
|
- **Power input**: internal AC PSU, `100-240V~ 50/60Hz 2A MAX`, DC output `53.5V 2.8A 150W`
|
||||||
|
- **Front panel LEDs**: `PWR`, `SYS`, per RJ45 port `Link/Act` and `PoE`, per SFP port 2.5G (green) and 10G (blue)
|
||||||
|
- **Stock firmware defaults**: web-managed PoE switch
|
||||||
|
|
||||||
|
### What works
|
||||||
|
|
||||||
|
- All eight 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps (PoE is not configurable via RTLPlayground)
|
||||||
|
- SFP+ port supporting 1G, 2.5G and 10G modules
|
||||||
|
- LEDs: green (2.5G) and amber (1G/100M/10M) per RJ45 port with activity, green (1G/2.5G) and blue (10G) on the SFP port, plus the `SYS` LED
|
||||||
|
|
||||||
|
### Photos
|
||||||
|
|
||||||
|
Front panel:
|
||||||
|
|
||||||
|
<img src="photos/PCB-AFGW_SWTG218ANS_V2.0.2/device_front.jpg" width="800" />
|
||||||
|
|
||||||
|
Board mounted in the case, with the internal PSU above it:
|
||||||
|
|
||||||
|
<img src="photos/PCB-AFGW_SWTG218ANS_V2.0.2/dev_top_w_pcb.jpg" width="800" />
|
||||||
|
|
||||||
|
### PCB overview
|
||||||
|
|
||||||
|
Top side:
|
||||||
|
|
||||||
|
<img src="photos/PCB-AFGW_SWTG218ANS_V2.0.2/pcb_front.jpg" width="800" />
|
||||||
|
|
||||||
|
Bottom side:
|
||||||
|
|
||||||
|
<img src="photos/PCB-AFGW_SWTG218ANS_V2.0.2/pcb_back.jpg" width="800" />
|
||||||
|
|
||||||
|
A 4-pad UART header with `RXD` / `TXD` silkscreened sits next to the right heatsink.
|
||||||
|
|
||||||
|
### Port layout
|
||||||
|
|
||||||
|
| Logical port | Physical port | Type |
|
||||||
|
|--------------|---------------|--------|
|
||||||
|
| 1-8 | 1-8 | RJ45 |
|
||||||
|
| 9 | 9 | SFP+ |
|
||||||
|
|
||||||
|
### LED configuration
|
||||||
|
|
||||||
|
RJ45 ports use LED SET0, the SFP+ port uses LED SET1. The board needs the custom
|
||||||
|
LED mux (`led_mux_custom = 1`), and `RTL837X_REG_LED_GLB_IO_EN` is written to
|
||||||
|
`0x7f24977f` in `machine_custom_init()` so the LED pins are enabled as wired here.
|
||||||
|
|
||||||
|
| SET | LED pin 0 | LED pin 1 |
|
||||||
|
|------|-----------------------------------------------|-------------------------------------------------------|
|
||||||
|
| SET0 | Green — lights on 2.5G link with activity | Amber — lights on 1G / 100M / 10M link with activity |
|
||||||
|
| SET1 | All speeds — lights on any link with activity | 10G — lights on 10G link with activity |
|
||||||
|
|
||||||
|
On the front panel this gives one bi-color `Link/Act` LED per RJ45 port (green at
|
||||||
|
2.5G, amber at 10/100/1000M, blinking with activity) and one `PoE` LED per RJ45
|
||||||
|
port, which is driven by the PoE hardware and not by the switch. The SFP+ port has
|
||||||
|
a green 2.5G LED and a blue 10G LED.
|
||||||
|
|
||||||
|
### SFP GPIO assignments
|
||||||
|
|
||||||
|
| SFP (logical 9) | pin_detect (ModAbs) | pin_los | pin_tx_disable | SerDes | I2C SDA | I2C SCL |
|
||||||
|
|-----------------|---------------------|---------|----------------|--------|------------------|----------------------|
|
||||||
|
| SFP | GPIO38 | GPIO_NA | GPIO_NA | SDS1 | GPIO39_I2C_SDA4 | GPIO40_I2C_SCL3_MDC1 |
|
||||||
|
|
||||||
|
### Machine configuration
|
||||||
|
|
||||||
|
```
|
||||||
|
make MACHINE=REALHD_PSW8_25MG
|
||||||
|
```
|
||||||
|
|
||||||
|
### Programming
|
||||||
|
|
||||||
|
The serial console runs at 8N1 on 115200 baud with the RTLPlayground firmware
|
||||||
|
(see the UART header note under *PCB overview*). The stock firmware baud rate 57600. The flash chip was 2MB.
|
||||||
|
|
||||||
|
### PoE
|
||||||
|
|
||||||
|
The 8 RJ45 ports support PoE, powered by the internal 150W AC PSU (DC output
|
||||||
|
53.5V 2.8A) mounted above the main board.
|
||||||
|
|
||||||
|
Note: RTLPlayground does not provide PoE management for this board. The PoE
|
||||||
|
hardware runs with its own configuration, the same as on the other PoE boards in
|
||||||
|
this project.
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.0 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 469 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
@@ -29,6 +29,7 @@ The following devices have been tested and are fully working:
|
|||||||
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V2.2](devices/2M-PCB23-V2_2.md) | 2M | 8 + 1 |
|
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V2.2](devices/2M-PCB23-V2_2.md) | 2M | 8 + 1 |
|
||||||
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.1](devices/2M-PCB23-V3_1.md) | 2M | 8 + 1 |
|
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.1](devices/2M-PCB23-V3_1.md) | 2M | 8 + 1 |
|
||||||
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.2](devices/2M-PCB23-V3_2.md) | 2M | 8 + 1 |
|
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.2](devices/2M-PCB23-V3_2.md) | 2M | 8 + 1 |
|
||||||
|
| keepLINK | KP-9000-9XHP-X | No | [2M-PCB51-ML-V1.1](devices/2M-PCB51-ML-V1_1.md) | 4M | 8 + 1 |
|
||||||
| LIANGUO | HYWS-SGT0108S | No | [2G5F_20G_V1.01](devices/HYWS-SGT0108S.md) | 0.5M | 8 + 1 |
|
| LIANGUO | HYWS-SGT0108S | No | [2G5F_20G_V1.01](devices/HYWS-SGT0108S.md) | 0.5M | 8 + 1 |
|
||||||
| LIANGUO | SWTG024AS | No | [SWTG024AS-v2.0-17452](devices/SWTG024AS.md) | 0.5M | 4 + 2 |
|
| LIANGUO | SWTG024AS | No | [SWTG024AS-v2.0-17452](devices/SWTG024AS.md) | 0.5M | 4 + 2 |
|
||||||
| LIANGUO | ZX-SWTGW215AS | Yes | [PCB-SWTG115AS-V2.0 / PCB-SWTG115AS-V2.1](devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
| LIANGUO | ZX-SWTGW215AS | Yes | [PCB-SWTG115AS-V2.0 / PCB-SWTG115AS-V2.1](devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
||||||
@@ -38,6 +39,7 @@ The following devices have been tested and are fully working:
|
|||||||
| MokerLink| 2G08110GSN | No | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | 0.5M | 8 + 1 |
|
| MokerLink| 2G08110GSN | No | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | 0.5M | 8 + 1 |
|
||||||
| Netcore | GS9 | No | [PB-2132](devices/PB-2132.md) | 4M | 8 + 1 |
|
| Netcore | GS9 | No | [PB-2132](devices/PB-2132.md) | 4M | 8 + 1 |
|
||||||
| ONT | ONT-S207CW-62TS-SE | No | [PCB-SWTG024AS-A-2.0.1](devices/ONT-S207CW-62TS-SE.md) | 0.5M | 4 + 2 |
|
| ONT | ONT-S207CW-62TS-SE | No | [PCB-SWTG024AS-A-2.0.1](devices/ONT-S207CW-62TS-SE.md) | 0.5M | 4 + 2 |
|
||||||
|
| RealHD | PSW8-25MG | Yes | [PCB-AFGW SWTG218ANS V2.0.2](devices/PCB-AFGW_SWTG218ANS_V2.0.2.md) | 2M | 8 + 1 |
|
||||||
| Ruiying | RY-4GT-2SX | No | [FG-4GT-2SX_V2.0](devices/FG-4GT-2SX_V2.0.md) | 4M | 4 + 2 |
|
| Ruiying | RY-4GT-2SX | No | [FG-4GT-2SX_V2.0](devices/FG-4GT-2SX_V2.0.md) | 4M | 4 + 2 |
|
||||||
| Ruiying | RY-8GT-1SX | No | [FG-8GT-1SX](devices/FG-8GT-1SX.md) | 1M | 8 + 1 |
|
| Ruiying | RY-8GT-1SX | No | [FG-8GT-1SX](devices/FG-8GT-1SX.md) | 1M | 8 + 1 |
|
||||||
| SICSOLINK| SL-G0402F | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
| SICSOLINK| SL-G0402F | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
||||||
|
|||||||
@@ -79,8 +79,11 @@ JSON polling of the visible section).
|
|||||||
computation no longer depends on uninitialised buffer content.
|
computation no longer depends on uninitialised buffer content.
|
||||||
- `version.h` is now written by a single atomic `printf` (change from
|
- `version.h` is now written by a single atomic `printf` (change from
|
||||||
upstream) instead of five separate `echo`s, so a parallel build
|
upstream) instead of five separate `echo`s, so a parallel build
|
||||||
(`make -j`) can no longer read a half-written copy. It stays in
|
(`make -j`) can no longer read a half-written copy. It depends on
|
||||||
`.PHONY` so it is regenerated on every build.
|
`FORCE`, so its recipe runs on every build, but the file is only
|
||||||
|
rewritten when its content changes. The minified copy in
|
||||||
|
`output/html_min/` is redone only when a web file, the list of web
|
||||||
|
files or `tools/minify.py` changes.
|
||||||
|
|
||||||
## Verification
|
## Verification
|
||||||
|
|
||||||
|
|||||||
+28
-13
@@ -16,7 +16,7 @@ d_system:"System",d_traffic:"Traffic",
|
|||||||
d_traffic_h:"packets/s, live",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX bad",d_rxbad:"RX bad",
|
d_traffic_h:"packets/s, live",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX bad",d_rxbad:"RX bad",
|
||||||
i_host:"Hostname",i_ip:"IP address",i_mask:"Netmask",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
i_host:"Hostname",i_ip:"IP address",i_mask:"Netmask",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
||||||
i_built:"Built",i_hw:"Hardware",i_temp:"Temperature",i_flash:"Flash",i_syslog:"Syslog",
|
i_built:"Built",i_hw:"Hardware",i_temp:"Temperature",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
p_state:"State",p_disabled:"disabled",p_up:"up",p_txgb:"TX good / bad",p_rxgb:"RX good / bad",
|
p_state:"State",p_disabled:"disabled",p_up:"up",
|
||||||
p_pkts:"pkts",p_module:"Module",p_temp:"Temperature",p_vcc:"Vcc",p_txbias:"TX bias",p_txpower:"TX power",
|
p_pkts:"pkts",p_module:"Module",p_temp:"Temperature",p_vcc:"Vcc",p_txbias:"TX bias",p_txpower:"TX power",
|
||||||
p_rxpower:"RX power",p_txfault:"TX fault",p_txdis:"TX disabled",p_rxlos:"RX LOS",p_adv:"Advertising",
|
p_rxpower:"RX power",p_txfault:"TX fault",p_txdis:"TX disabled",p_rxlos:"RX LOS",p_adv:"Advertising",
|
||||||
pt_title:"Port configuration",pt_conn:"Devices learned",pt_speed:"Speed",pt_mtu:"MTU",
|
pt_title:"Port configuration",pt_conn:"Devices learned",pt_speed:"Speed",pt_mtu:"MTU",
|
||||||
@@ -147,7 +147,7 @@ d_system:"システム",d_traffic:"トラフィック",
|
|||||||
d_traffic_h:"パケット/秒、リアルタイム",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 異常",d_rxbad:"RX 異常",
|
d_traffic_h:"パケット/秒、リアルタイム",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 異常",d_rxbad:"RX 異常",
|
||||||
i_host:"ホスト名",i_ip:"IP アドレス",i_mask:"ネットマスク",i_gw:"ゲートウェイ",i_mac:"MAC",i_fw:"ファームウェア",
|
i_host:"ホスト名",i_ip:"IP アドレス",i_mask:"ネットマスク",i_gw:"ゲートウェイ",i_mac:"MAC",i_fw:"ファームウェア",
|
||||||
i_built:"ビルド日",i_hw:"ハードウェア",i_temp:"温度",i_flash:"フラッシュ",i_syslog:"Syslog",
|
i_built:"ビルド日",i_hw:"ハードウェア",i_temp:"温度",i_flash:"フラッシュ",i_syslog:"Syslog",
|
||||||
p_state:"状態",p_disabled:"無効",p_up:"アップ",p_txgb:"TX 正常 / 異常",p_rxgb:"RX 正常 / 異常",
|
p_state:"状態",p_disabled:"無効",p_up:"アップ",
|
||||||
p_pkts:"pkts",p_module:"モジュール",p_temp:"温度",p_vcc:"電圧",p_txbias:"TX バイアス",p_txpower:"TX 電力",
|
p_pkts:"pkts",p_module:"モジュール",p_temp:"温度",p_vcc:"電圧",p_txbias:"TX バイアス",p_txpower:"TX 電力",
|
||||||
p_rxpower:"RX 電力",p_txfault:"TX 障害",p_txdis:"TX 無効",p_rxlos:"RX 信号ロス",p_adv:"アドバタイズ",
|
p_rxpower:"RX 電力",p_txfault:"TX 障害",p_txdis:"TX 無効",p_rxlos:"RX 信号ロス",p_adv:"アドバタイズ",
|
||||||
pt_title:"ポート設定",pt_conn:"学習済みデバイス",pt_speed:"速度",pt_mtu:"MTU",
|
pt_title:"ポート設定",pt_conn:"学習済みデバイス",pt_speed:"速度",pt_mtu:"MTU",
|
||||||
@@ -260,7 +260,7 @@ d_system:"系统",d_traffic:"流量",
|
|||||||
d_traffic_h:"包/秒,实时",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 错误",d_rxbad:"RX 错误",
|
d_traffic_h:"包/秒,实时",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 错误",d_rxbad:"RX 错误",
|
||||||
i_host:"主机名",i_ip:"IP 地址",i_mask:"子网掩码",i_gw:"网关",i_mac:"MAC",i_fw:"固件",
|
i_host:"主机名",i_ip:"IP 地址",i_mask:"子网掩码",i_gw:"网关",i_mac:"MAC",i_fw:"固件",
|
||||||
i_built:"构建日期",i_hw:"硬件",i_temp:"温度",i_flash:"Flash",i_syslog:"Syslog",
|
i_built:"构建日期",i_hw:"硬件",i_temp:"温度",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
p_state:"状态",p_disabled:"已禁用",p_up:"已连接",p_txgb:"TX 正常 / 错误",p_rxgb:"RX 正常 / 错误",
|
p_state:"状态",p_disabled:"已禁用",p_up:"已连接",
|
||||||
p_pkts:"个包",p_module:"模块",p_temp:"温度",p_vcc:"供电电压",p_txbias:"TX 偏置电流",p_txpower:"TX 光功率",
|
p_pkts:"个包",p_module:"模块",p_temp:"温度",p_vcc:"供电电压",p_txbias:"TX 偏置电流",p_txpower:"TX 光功率",
|
||||||
p_rxpower:"RX 光功率",p_txfault:"TX 故障",p_txdis:"TX 禁用",p_rxlos:"RX 信号丢失",p_adv:"通告能力",
|
p_rxpower:"RX 光功率",p_txfault:"TX 故障",p_txdis:"TX 禁用",p_rxlos:"RX 信号丢失",p_adv:"通告能力",
|
||||||
pt_title:"端口配置",pt_conn:"已学习设备",pt_speed:"速率",pt_mtu:"MTU",
|
pt_title:"端口配置",pt_conn:"已学习设备",pt_speed:"速率",pt_mtu:"MTU",
|
||||||
@@ -373,7 +373,7 @@ d_system:"Sistema",d_traffic:"Tráfico",
|
|||||||
d_traffic_h:"paquetes/s, en vivo",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX erróneos",d_rxbad:"RX erróneos",
|
d_traffic_h:"paquetes/s, en vivo",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX erróneos",d_rxbad:"RX erróneos",
|
||||||
i_host:"Nombre de host",i_ip:"Dirección IP",i_mask:"Máscara de red",i_gw:"Puerta de enlace",i_mac:"MAC",i_fw:"Firmware",
|
i_host:"Nombre de host",i_ip:"Dirección IP",i_mask:"Máscara de red",i_gw:"Puerta de enlace",i_mac:"MAC",i_fw:"Firmware",
|
||||||
i_built:"Compilado",i_hw:"Hardware",i_flash:"Flash",i_syslog:"Syslog",
|
i_built:"Compilado",i_hw:"Hardware",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
p_state:"Estado",p_disabled:"deshabilitado",p_up:"activo",p_txgb:"TX correctos / erróneos",p_rxgb:"RX correctos / erróneos",
|
p_state:"Estado",p_disabled:"deshabilitado",p_up:"activo",
|
||||||
p_pkts:"paquetes",p_module:"Módulo",p_temp:"Temperatura",p_vcc:"Vcc",p_txbias:"Polarización TX",p_txpower:"Potencia TX",
|
p_pkts:"paquetes",p_module:"Módulo",p_temp:"Temperatura",p_vcc:"Vcc",p_txbias:"Polarización TX",p_txpower:"Potencia TX",
|
||||||
p_rxpower:"Potencia RX",p_txfault:"Fallo TX",p_txdis:"TX deshabilitado",p_rxlos:"Pérdida RX (LOS)",p_adv:"Anunciado",
|
p_rxpower:"Potencia RX",p_txfault:"Fallo TX",p_txdis:"TX deshabilitado",p_rxlos:"Pérdida RX (LOS)",p_adv:"Anunciado",
|
||||||
pt_title:"Configuración de puerto",pt_conn:"Dispositivos aprendidos",pt_speed:"Velocidad",pt_mtu:"MTU",
|
pt_title:"Configuración de puerto",pt_conn:"Dispositivos aprendidos",pt_speed:"Velocidad",pt_mtu:"MTU",
|
||||||
@@ -472,7 +472,7 @@ fw_timeout:"el switch no ha vuelto tras 150 s: comprueba la alimentación / cons
|
|||||||
fr:{
|
fr:{
|
||||||
nav_dash:"Tableau de bord",nav_ports:"Ports",nav_stp:"Arborescence",nav_stats:"Statistiques",
|
nav_dash:"Tableau de bord",nav_ports:"Ports",nav_stp:"Arborescence",nav_stats:"Statistiques",
|
||||||
nav_vlan:"LANs virtuels",nav_l2:"Table MAC",nav_mirror:"Mise en mirroir",nav_lag:"Aggrégation",nav_eee:"Energie",
|
nav_vlan:"LANs virtuels",nav_l2:"Table MAC",nav_mirror:"Mise en mirroir",nav_lag:"Aggrégation",nav_eee:"Energie",
|
||||||
nav_bw:"Bande passante",nav_system:"Système",nav_fw:"Micro logiciel",
|
nav_bw:"Bande passante",nav_system:"Système",nav_fw:"Micro logiciel",nav_lldp:"Couche de Liaison",
|
||||||
hdr_dirty:"Changements non sauvegardés",hdr_dirty_t:"La configuration utilisée diffère de celle au démarrage",
|
hdr_dirty:"Changements non sauvegardés",hdr_dirty_t:"La configuration utilisée diffère de celle au démarrage",
|
||||||
hdr_save:"Sauvegarder en flash",hdr_save_t:"Maintenir la configuration actuelle en flash",
|
hdr_save:"Sauvegarder en flash",hdr_save_t:"Maintenir la configuration actuelle en flash",
|
||||||
th_auto:"Système",th_auto_sel:"Système (sélénisé)",sy_display:"Affichage",sy_theme:"Thème",sy_display_note:"Enregistré seulement dans ce navigateur.",th_light:"Clair",th_dark:"Sombre",
|
th_auto:"Système",th_auto_sel:"Système (sélénisé)",sy_display:"Affichage",sy_theme:"Thème",sy_display_note:"Enregistré seulement dans ce navigateur.",th_light:"Clair",th_dark:"Sombre",
|
||||||
@@ -485,7 +485,7 @@ d_system:"Système",d_traffic:"Trafic",
|
|||||||
d_traffic_h:"paquets/s (en direct)",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX KO",d_rxbad:"RX KO",
|
d_traffic_h:"paquets/s (en direct)",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX KO",d_rxbad:"RX KO",
|
||||||
i_host:"Nom d'hote",i_ip:"Adresse IP",i_mask:"Masque réseau",i_gw:"Passerelle",i_mac:"Adresse MAC",i_fw:"Micro logiciel",
|
i_host:"Nom d'hote",i_ip:"Adresse IP",i_mask:"Masque réseau",i_gw:"Passerelle",i_mac:"Adresse MAC",i_fw:"Micro logiciel",
|
||||||
i_built:"Compilé le",i_hw:"Matériel",i_temp:"Température",i_flash:"Taille Flash",i_syslog:"Journal système",
|
i_built:"Compilé le",i_hw:"Matériel",i_temp:"Température",i_flash:"Taille Flash",i_syslog:"Journal système",
|
||||||
p_state:"Etat",p_disabled:"Inactif",p_up:"Actif",p_txgb:"TX bon / mauvais",p_rxgb:"RX bon / mauvais",
|
p_state:"Etat",p_disabled:"Inactif",p_up:"Actif",
|
||||||
p_pkts:"paquets",p_module:"Module",p_temp:"Température",p_vcc:"Vcc",p_txbias:"TX biais",p_txpower:"TX puissance",
|
p_pkts:"paquets",p_module:"Module",p_temp:"Température",p_vcc:"Vcc",p_txbias:"TX biais",p_txpower:"TX puissance",
|
||||||
p_rxpower:"RX puissance",p_txfault:"TX erreur",p_txdis:"TX désactivé",p_rxlos:"RX pertes de signaux",p_adv:"Capacités",
|
p_rxpower:"RX puissance",p_txfault:"TX erreur",p_txdis:"TX désactivé",p_rxlos:"RX pertes de signaux",p_adv:"Capacités",
|
||||||
pt_title:"Configuration du port",pt_conn:"Appareils appris",pt_speed:"Vitesse",pt_mtu:"MTU",
|
pt_title:"Configuration du port",pt_conn:"Appareils appris",pt_speed:"Vitesse",pt_mtu:"MTU",
|
||||||
@@ -509,6 +509,7 @@ stp_en_q:"Activer l'arbrescence?",
|
|||||||
stp_en_d:"Les ports sont d'abord bloqués et cela prend deux fois le délai de retransmission pour atteindre l'état de retransmission; les ports en bordures recouvrent immédiatement leur état.",
|
stp_en_d:"Les ports sont d'abord bloqués et cela prend deux fois le délai de retransmission pour atteindre l'état de retransmission; les ports en bordures recouvrent immédiatement leur état.",
|
||||||
stp_dis_q:"Désactiver l'arborescence ?",stp_dis_d:"Tous les ports vont être retransmis; la protection de boucles est perdue.",
|
stp_dis_q:"Désactiver l'arborescence ?",stp_dis_d:"Tous les ports vont être retransmis; la protection de boucles est perdue.",
|
||||||
stp_cost_err:"Le coût du chemin doit être compris entre 0 et 200000000",
|
stp_cost_err:"Le coût du chemin doit être compris entre 0 et 200000000",
|
||||||
|
lldp_enabled: "Activer LLDP",lldp_title:"Protocole de découverte de la couche de liason (LLDP)",lldp_portname:"Nom",lldp_enable:"Envoi de trames",
|
||||||
st_title:"Statiqtique du port",st_h:"cumul depuis le démarrage",st_txg:"TX OK",st_txb:"TX KO",st_rxg:"RX OK",
|
st_title:"Statiqtique du port",st_h:"cumul depuis le démarrage",st_txg:"TX OK",st_txb:"TX KO",st_rxg:"RX OK",
|
||||||
st_rxb:"RX KO",st_details:"Détails",st_counters:"Compteur MIB",st_nonzero:"non-zero seulement",
|
st_rxb:"RX KO",st_details:"Détails",st_counters:"Compteur MIB",st_nonzero:"non-zero seulement",
|
||||||
st_autoref:"rafraichissement automatique",st_counter:"Compteur",st_value:"Valeur",st_fail:"Erreur au chargement des compteurs",
|
st_autoref:"rafraichissement automatique",st_counter:"Compteur",st_value:"Valeur",st_fail:"Erreur au chargement des compteurs",
|
||||||
@@ -542,6 +543,9 @@ e_idle:"Inactif",e_na:"N/A",
|
|||||||
bw_title:"Limitations de bande passante",bw_h:"Mbit/s, 0.016-10000",bw_in:"Limite entrante",bw_out:"Limite sortante",
|
bw_title:"Limitations de bande passante",bw_h:"Mbit/s, 0.016-10000",bw_in:"Limite entrante",bw_out:"Limite sortante",
|
||||||
bw_exceed:"Lorsque dépassé",bw_fc:"Limiter",bw_drop:"Rejetter",
|
bw_exceed:"Lorsque dépassé",bw_fc:"Limiter",bw_drop:"Rejetter",
|
||||||
bw_in_err:"La limite entrante doit être comprise entre 0.016 et 10000 Mbit/s",bw_out_err:"La limite sortante doit être comprise entre 0.016 et 10000 Mbit/s",
|
bw_in_err:"La limite entrante doit être comprise entre 0.016 et 10000 Mbit/s",bw_out_err:"La limite sortante doit être comprise entre 0.016 et 10000 Mbit/s",
|
||||||
|
sc_title:"Contrôle des tempêtes",sc_h:"par port et par type de diffusion (générale ou groupée), vide = inactif",sc_bcast:"Générale (Broadcast)",sc_mcast:"Groupée (Multicast)",
|
||||||
|
sc_ucast:"Unicast inconnu",sc_umcast:"Multicast inconnu",sc_err:" La limite de tempête doit être comprise entre 1 à 1048575 pps ou 1 à 10000000 kbit/s",
|
||||||
|
sc_note:"Les trames de chacun des types ci-dessus dépassant les limites sont abandonnées lorsqu'elles arrivent sur le communtateur.",
|
||||||
sy_network:"Réseau",sy_dhcp:"Uiliser DHCP",sy_dhcp_t:"Aquérir l'adresse via le protocole DHCP",sy_services:"Services",
|
sy_network:"Réseau",sy_dhcp:"Uiliser DHCP",sy_dhcp_t:"Aquérir l'adresse via le protocole DHCP",sy_services:"Services",
|
||||||
sy_igmp:"Surveillance IGMP",sy_sysip:"IP du serveur...",sy_server:"Serveur",sy_port:"Port",
|
sy_igmp:"Surveillance IGMP",sy_sysip:"IP du serveur...",sy_server:"Serveur",sy_port:"Port",
|
||||||
sy_sesstmo:"Temps mort de session (s)",sy_sesstmo_err:"Le temps morts de session doit être compris en 1-65535 s",
|
sy_sesstmo:"Temps mort de session (s)",sy_sesstmo_err:"Le temps morts de session doit être compris en 1-65535 s",
|
||||||
@@ -555,7 +559,14 @@ sy_ip_err:"Erreur d'IP / masque réseau / passerelle",sy_host_err:"Nom d'hôte :
|
|||||||
sy_net_q:"Appliquer les paramètres réseau?",sy_net_d:"L'adresse IP de management va devenir {ip}: merci de réouvrir le page depuis cette adresse.",
|
sy_net_q:"Appliquer les paramètres réseau?",sy_net_d:"L'adresse IP de management va devenir {ip}: merci de réouvrir le page depuis cette adresse.",
|
||||||
sy_ip_changed:"L'adresse IP a changée, reconnectez-vous à http://{ip}/",sy_dhcp_q:"Passer en DHCP?",
|
sy_ip_changed:"L'adresse IP a changée, reconnectez-vous à http://{ip}/",sy_dhcp_q:"Passer en DHCP?",
|
||||||
sy_dhcp_d:"Le commutateur va demander une addresse via le DHCP. Vous devrez rechercher sa prochaine adresse IP pour vous reconnecter.",
|
sy_dhcp_d:"Le commutateur va demander une addresse via le DHCP. Vous devrez rechercher sa prochaine adresse IP pour vous reconnecter.",
|
||||||
sy_sysip_err:"Adresse IP du serveur Syslog invalide",sy_sysport_err:"Le port Syslog doit être compris entre 1 et 65535",
|
sy_sysip_err:"Adresse IP du serveur Syslog invalide",sy_dns1:"DNS principal",sy_dns2:"DNS secondaire",sy_dns_err:"Adresse IP du DNS invalide",sy_dns_dhcp:"émis par le DHCP: {ip}",
|
||||||
|
sy_time:"Temps",sy_ntp:"NTP",sy_ntpsrv:"Serveur NTP",sy_ntpsrv_p:"Nom d'hôte ou adresse IPv4",sy_ntpint:"intervalle de scrutation [min]",
|
||||||
|
sy_tz:"Fuseau horaire",sy_dst:"Heure d'été",sy_dst_eu:"Europe",
|
||||||
|
sy_dst_us:"Etats-Unis",sy_now:"Heure locale",
|
||||||
|
sy_sync:"Dernière synchronisation",sy_ntpaddr:"Adresse du serveur",sy_nosync:"Désynchronisé",sy_waiting:"En attente du serveur",
|
||||||
|
sy_ago:"depuis {n} minutes",sy_ntp_err:"Entrez le nom d'hôte ou l'adresse IPv4 du serveur NTP",sy_ntpint_err:"L'intervalle de scrutation doit être compris entre 1 et 1440",
|
||||||
|
sy_time_note:"Le commutateur n'a pas d'horloge sauvegardée par batterie: L'heure est donc perdue à chaque redémarrage et doit être récupérée grâce au serveur NTP une fois le réseau fonctionnel. Sauvegardez en mémoire flash pour enregistrer les paramètres.",
|
||||||
|
sy_sysport_err:"Le port Syslog doit être compris entre 1 et 65535",
|
||||||
sy_pw_len:"Mot de passe : 1 à 20 caractères",sy_pw_space:"Le mot de passe ne doit pas contenir d'espaces",sy_pw_match:"Les mots de passe ne correspondent pas",
|
sy_pw_len:"Mot de passe : 1 à 20 caractères",sy_pw_space:"Le mot de passe ne doit pas contenir d'espaces",sy_pw_match:"Les mots de passe ne correspondent pas",
|
||||||
sy_pw_q:"Changer le mot de passe d'administration?",sy_pw_d:"Cela prend effet immédiatement dès la prochaine connection. Enregistrez en Flash pour rendre la modification persistante.",
|
sy_pw_q:"Changer le mot de passe d'administration?",sy_pw_d:"Cela prend effet immédiatement dès la prochaine connection. Enregistrez en Flash pour rendre la modification persistante.",
|
||||||
sy_reboot_q:"Redémarrer le commutateur ?",sy_reboot_d:"Il y a des paramètres NON SAUVEGARDES qui vont être perdus. Sauvegardez-les au préalable en mémoire flash si vous souhaitez les conserver.",
|
sy_reboot_q:"Redémarrer le commutateur ?",sy_reboot_d:"Il y a des paramètres NON SAUVEGARDES qui vont être perdus. Sauvegardez-les au préalable en mémoire flash si vous souhaitez les conserver.",
|
||||||
@@ -602,7 +613,7 @@ d_system:"System",d_traffic:"Datenverkehr",
|
|||||||
d_traffic_h:"Pakete/s, live",d_txpps:"TX Pakete/s",d_rxpps:"RX Pakete/s",d_txbad:"TX fehlerhaft",d_rxbad:"RX fehlerhaft",
|
d_traffic_h:"Pakete/s, live",d_txpps:"TX Pakete/s",d_rxpps:"RX Pakete/s",d_txbad:"TX fehlerhaft",d_rxbad:"RX fehlerhaft",
|
||||||
i_host:"Hostname",i_ip:"IP-Adresse",i_mask:"Netzmaske",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
i_host:"Hostname",i_ip:"IP-Adresse",i_mask:"Netzmaske",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
||||||
i_built:"Erstellt",i_hw:"Hardware",i_temp:"Temperatur",i_flash:"Flash",i_syslog:"Syslog",
|
i_built:"Erstellt",i_hw:"Hardware",i_temp:"Temperatur",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
p_state:"Zustand",p_disabled:"deaktiviert",p_up:"verbunden",p_txgb:"TX gut / fehlerhaft",p_rxgb:"RX gut / fehlerhaft",
|
p_state:"Zustand",p_disabled:"deaktiviert",p_up:"verbunden",
|
||||||
p_pkts:"Pakete",p_module:"Modul",p_temp:"Temperatur",p_vcc:"Vcc",p_txbias:"TX-Bias",p_txpower:"Sendeleistung",
|
p_pkts:"Pakete",p_module:"Modul",p_temp:"Temperatur",p_vcc:"Vcc",p_txbias:"TX-Bias",p_txpower:"Sendeleistung",
|
||||||
p_rxpower:"Empfangsleistung",p_txfault:"TX-Fehler",p_txdis:"TX deaktiviert",p_rxlos:"RX LOS",p_adv:"Angeboten",
|
p_rxpower:"Empfangsleistung",p_txfault:"TX-Fehler",p_txdis:"TX deaktiviert",p_rxlos:"RX LOS",p_adv:"Angeboten",
|
||||||
pt_title:"Port-Konfiguration",pt_conn:"Gelernte Geräte",pt_speed:"Geschwindigkeit",pt_mtu:"MTU",
|
pt_title:"Port-Konfiguration",pt_conn:"Gelernte Geräte",pt_speed:"Geschwindigkeit",pt_mtu:"MTU",
|
||||||
@@ -836,6 +847,7 @@ function isConfCmd(line){
|
|||||||
function setDirty(d){
|
function setDirty(d){
|
||||||
S.dirty=d;
|
S.dirty=d;
|
||||||
$("dirty").classList.toggle("show",d);
|
$("dirty").classList.toggle("show",d);
|
||||||
|
$("saveBtn").classList.toggle("pri",d);
|
||||||
}
|
}
|
||||||
function postCmd(cmd,quiet){
|
function postCmd(cmd,quiet){
|
||||||
return api("/cmd",{method:"POST",body:cmd}).then(function(r){
|
return api("/cmd",{method:"POST",body:cmd}).then(function(r){
|
||||||
@@ -1024,8 +1036,10 @@ function portRows(p){
|
|||||||
var rows=[[t("c_port"),String(p.portNum)],[t("c_type"),p.isSFP?"SFP":"RJ45"]];
|
var rows=[[t("c_port"),String(p.portNum)],[t("c_type"),p.isSFP?"SFP":"RJ45"]];
|
||||||
if(p.name)rows.push([t("c_name"),p.name]);
|
if(p.name)rows.push([t("c_name"),p.name]);
|
||||||
rows.push([t("p_state"),!p.enabled?t("p_disabled"):(p.link>0?t("p_up")+" "+LINKS[p.link]:t("c_down"))]);
|
rows.push([t("p_state"),!p.enabled?t("p_disabled"):(p.link>0?t("p_up")+" "+LINKS[p.link]:t("c_down"))]);
|
||||||
rows.push([t("p_txgb"),BigInt(p.txG)+" / "+BigInt(p.txB)+" "+t("p_pkts")]);
|
rows.push([t("st_txg"),BigInt(p.txG)+" "+t("p_pkts")]);
|
||||||
rows.push([t("p_rxgb"),BigInt(p.rxG)+" / "+BigInt(p.rxB)+" "+t("p_pkts")]);
|
rows.push([t("st_txb"),BigInt(p.txB)+" "+t("p_pkts")]);
|
||||||
|
rows.push([t("st_rxg"),BigInt(p.rxG)+" "+t("p_pkts")]);
|
||||||
|
rows.push([t("st_rxb"),BigInt(p.rxB)+" "+t("p_pkts")]);
|
||||||
if(p.isSFP){
|
if(p.isSFP){
|
||||||
if(p.sfp_vendor)rows.push([t("p_module"),[p.sfp_vendor,p.sfp_model,p.sfp_serial].filter(Boolean).join(" / ")]);
|
if(p.sfp_vendor)rows.push([t("p_module"),[p.sfp_vendor,p.sfp_model,p.sfp_serial].filter(Boolean).join(" / ")]);
|
||||||
var ext=p.sfp_options&0x40;
|
var ext=p.sfp_options&0x40;
|
||||||
@@ -2243,14 +2257,14 @@ var CONF_OVERWRITE=[
|
|||||||
/^ntp\s+server\b/,/^ntp\s+interval\b/,/^ntp\s+timezone\b/,/^ntp\s+dst\b/,
|
/^ntp\s+server\b/,/^ntp\s+interval\b/,/^ntp\s+timezone\b/,/^ntp\s+dst\b/,
|
||||||
/^vlan\s+\d{1,4}\s+mgmt$/,/^vlan\s+\d{1,4}(?!\s+mgmt\b)/,
|
/^vlan\s+\d{1,4}\s+mgmt$/,/^vlan\s+\d{1,4}(?!\s+mgmt\b)/,
|
||||||
/^pvid\s+\d{1,2}\b/,
|
/^pvid\s+\d{1,2}\b/,
|
||||||
/^port\s+\d{1,2}(?!\s+name\b)/,/^port\s+\d{1,2}\s+name\b/,
|
/^port\s+\d{1,2}(?!\s+(name|lldp)\b)/,/^port\s+\d{1,2}\s+name\b/,
|
||||||
/^mirror\b/,
|
/^mirror\b/,
|
||||||
/^lag\s+\d\b/,/^laghash\s+\d\b/,/^isolate\s+\d{1,2}\b/,
|
/^lag\s+\d\b/,/^laghash\s+\d\b/,/^isolate\s+\d{1,2}\b/,
|
||||||
/^stp\s+(prio|hello|maxage|fwd|txhold|version)\b/,
|
/^stp\s+(prio|hello|maxage|fwd|txhold|version)\b/,
|
||||||
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+(edge|cost|prio|guard|filter|p2p)\b/,
|
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+(edge|cost|prio|guard|filter|p2p)\b/,
|
||||||
/^igmp\b/,/^mtu\s+\d{1,2}\b/,/^storm\s+\d{1,2}\s+(bcast|mcast|ucast|umcast)\b/,
|
/^igmp\b/,/^mtu\s+\d{1,2}\b/,/^storm\s+\d{1,2}\s+(bcast|mcast|ucast|umcast)\b/,
|
||||||
];
|
];
|
||||||
var CONF_TOGGLE=[/^(syslog)\s+(on|off)$/,/^(ntp)\s+(on|off)$/,/^(stp)\s+(on|off)$/,/^(stp\s+(port\s+\d{1,2}|lag\s+[1-4]))\s+(on|off)$/];
|
var CONF_TOGGLE=[/^(syslog)\s+(on|off)$/,/^(ntp)\s+(on|off)$/,/^(stp)\s+(on|off)$/,/^(lldp)\s+(on|off)$/,/^(stp\s+(port\s+\d{1,2}|lag\s+[1-4]))\s+(on|off)$/];
|
||||||
function mergeConf(base,texts){
|
function mergeConf(base,texts){
|
||||||
var conf=base.slice();
|
var conf=base.slice();
|
||||||
function drop(rx){conf=conf.filter(function(c){return!rx.test(c)})}
|
function drop(rx){conf=conf.filter(function(c){return!rx.test(c)})}
|
||||||
@@ -2268,6 +2282,7 @@ function mergeConf(base,texts){
|
|||||||
}
|
}
|
||||||
if((m=line.match(/^lag (\d) lacp off$/))){drop(new RegExp("^lag "+m[1]+" lacp( |$)"));return;}
|
if((m=line.match(/^lag (\d) lacp off$/))){drop(new RegExp("^lag "+m[1]+" lacp( |$)"));return;}
|
||||||
if(line==="mirror off"){drop(/^mirror /);return;}
|
if(line==="mirror off"){drop(/^mirror /);return;}
|
||||||
|
if((m=line.match(/^(port \d{1,2} lldp) (permit|block)$/))){drop(new RegExp("^"+m[1]+" (permit|block)$"));conf.push(line);return;}
|
||||||
if(!isConfCmd(line))return;
|
if(!isConfCmd(line))return;
|
||||||
if((m=line.match(/^ingress (.+)$/))){
|
if((m=line.match(/^ingress (.+)$/))){
|
||||||
if(/^[tua]$/.test(m[1])){drop(/^ingress /);conf.push(line);return;}
|
if(/^[tua]$/.test(m[1])){drop(/^ingress /);conf.push(line);return;}
|
||||||
@@ -2300,7 +2315,7 @@ function mergeConf(base,texts){
|
|||||||
var key=line.match(rx)[0];
|
var key=line.match(rx)[0];
|
||||||
conf=conf.filter(function(item){
|
conf=conf.filter(function(item){
|
||||||
return!(item===key||(item.indexOf(key+" ")===0
|
return!(item===key||(item.indexOf(key+" ")===0
|
||||||
&&!/\smgmt$/.test(item)&&item.indexOf(key+" name ")!==0));
|
&&!/\smgmt$/.test(item)&&item.indexOf(key+" name ")!==0&&item.indexOf(key+" lldp ")!==0));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-6
@@ -33,7 +33,7 @@
|
|||||||
html,body{height:100%}
|
html,body{height:100%}
|
||||||
body{
|
body{
|
||||||
font:14px/1.45 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
|
font:14px/1.45 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
|
||||||
background:var(--bg);color:var(--fg);display:flex;
|
background:var(--bg);color:var(--fg);display:flex;overflow:hidden;
|
||||||
}
|
}
|
||||||
button,input,select,textarea{font:inherit;color:var(--fg)}
|
button,input,select,textarea{font:inherit;color:var(--fg)}
|
||||||
a{color:var(--ac);text-decoration:none}
|
a{color:var(--ac);text-decoration:none}
|
||||||
@@ -72,8 +72,8 @@ select.ctl,button.ctl{
|
|||||||
button.pri{background:var(--ac);color:var(--acfg);border-color:transparent;font-weight:600}
|
button.pri{background:var(--ac);color:var(--acfg);border-color:transparent;font-weight:600}
|
||||||
button.pri:hover,button.ctl:hover{filter:brightness(1.07)}
|
button.pri:hover,button.ctl:hover{filter:brightness(1.07)}
|
||||||
button:disabled{opacity:.45;cursor:default;filter:none}
|
button:disabled{opacity:.45;cursor:default;filter:none}
|
||||||
main{padding:18px 20px 40px;max-width:1400px;width:100%}
|
main{padding:18px 20px 40px;width:100%;overflow-y:auto;}
|
||||||
section.tab{display:none}
|
section.tab{display:none;max-width:1400px;}
|
||||||
section.tab.act{display:block}
|
section.tab.act{display:block}
|
||||||
.card{
|
.card{
|
||||||
background:var(--panel);border:1px solid var(--bd);border-radius:10px;
|
background:var(--panel);border:1px solid var(--bd);border-radius:10px;
|
||||||
@@ -89,6 +89,7 @@ table.t th{
|
|||||||
padding:6px 8px;border-bottom:1px solid var(--bd);white-space:nowrap;
|
padding:6px 8px;border-bottom:1px solid var(--bd);white-space:nowrap;
|
||||||
}
|
}
|
||||||
table.t th[data-sort]{cursor:pointer;user-select:none}
|
table.t th[data-sort]{cursor:pointer;user-select:none}
|
||||||
|
table.t th.num{text-align:right}
|
||||||
table.t td{padding:6px 8px;border-bottom:1px solid var(--bd);vertical-align:middle}
|
table.t td{padding:6px 8px;border-bottom:1px solid var(--bd);vertical-align:middle}
|
||||||
table.t tr:last-child td{border-bottom:0}
|
table.t tr:last-child td{border-bottom:0}
|
||||||
table.t tr:hover td{background:var(--sel)}
|
table.t tr:hover td{background:var(--sel)}
|
||||||
@@ -223,7 +224,7 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
<span id="ttitle"></span>
|
<span id="ttitle"></span>
|
||||||
<div id="strip"></div>
|
<div id="strip"></div>
|
||||||
<span id="dirty" data-i18n="hdr_dirty" data-i18n-t="hdr_dirty_t">unsaved changes</span>
|
<span id="dirty" data-i18n="hdr_dirty" data-i18n-t="hdr_dirty_t">unsaved changes</span>
|
||||||
<button class="ctl pri" id="saveBtn" data-i18n="hdr_save" data-i18n-t="hdr_save_t">Save to flash</button>
|
<button class="ctl" id="saveBtn" data-i18n="hdr_save" data-i18n-t="hdr_save_t">Save to flash</button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
@@ -437,8 +438,8 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
<p class="small mut" style="margin-top:8px" data-i18n="sy_time_note">The switch has no battery backed clock.</p>
|
<p class="small mut" style="margin-top:8px" data-i18n="sy_time_note">The switch has no battery backed clock.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card"><h2 data-i18n="sy_password">Admin password</h2>
|
<div class="card"><h2 data-i18n="sy_password">Admin password</h2>
|
||||||
<label class="row"><span class="lb" data-i18n="sy_newpw">New password</span><input class="in" id="sy-pw1" type="password" maxlength="20"></label>
|
<label class="row"><span class="lb" data-i18n="sy_newpw">New password</span><input class="in" id="sy-pw1" type="password" autocomplete="new-password" maxlength="20"></label>
|
||||||
<label class="row"><span class="lb" data-i18n="sy_repeat">Repeat</span><input class="in" id="sy-pw2" type="password" maxlength="20"></label>
|
<label class="row"><span class="lb" data-i18n="sy_repeat">Repeat</span><input class="in" id="sy-pw2" type="password" autocomplete="new-password" maxlength="20"></label>
|
||||||
<button class="ctl pri" id="sy-pwapply" style="margin-top:8px" data-i18n="sy_pwapply">Change password</button>
|
<button class="ctl pri" id="sy-pwapply" style="margin-top:8px" data-i18n="sy_pwapply">Change password</button>
|
||||||
<p class="small mut" style="margin-top:8px" data-i18n="sy_pw_note">Takes effect immediately; save to flash to keep it after reboot.</p>
|
<p class="small mut" style="margin-top:8px" data-i18n="sy_pw_note">Takes effect immediately; save to flash to keep it after reboot.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+9
-39
@@ -6,12 +6,12 @@
|
|||||||
#include "cmd_parser.h"
|
#include "cmd_parser.h"
|
||||||
#include "rtl837x_flash.h"
|
#include "rtl837x_flash.h"
|
||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
|
#include "sessions.h"
|
||||||
#include "html_data.h"
|
#include "html_data.h"
|
||||||
|
|
||||||
// #define DEBUG
|
// #define DEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define SESSION_ID_LENGTH 12
|
|
||||||
#define SESSION_TIMEOUT_DEFAULT 200
|
#define SESSION_TIMEOUT_DEFAULT 200
|
||||||
|
|
||||||
/* Seconds of inactivity after which a session cookie stops validating.
|
/* Seconds of inactivity after which a session cookie stops validating.
|
||||||
@@ -75,10 +75,9 @@ __xdata uint8_t postbody_endpoint;
|
|||||||
__xdata uint16_t postbody_start;
|
__xdata uint16_t postbody_start;
|
||||||
|
|
||||||
__xdata char passwd[21];
|
__xdata char passwd[21];
|
||||||
__xdata char session_id[SESSION_ID_LENGTH + 1];
|
// Up to four logins at once, see sessions.c
|
||||||
__xdata uint8_t authenticated;
|
__xdata uint8_t authenticated;
|
||||||
__xdata uint32_t now;
|
__xdata uint32_t now;
|
||||||
__xdata uint32_t last_session_use;
|
|
||||||
|
|
||||||
#define TSTATE_NONE 0
|
#define TSTATE_NONE 0
|
||||||
#define TSTATE_TX 1
|
#define TSTATE_TX 1
|
||||||
@@ -109,6 +108,7 @@ void httpd_init(void) __banked
|
|||||||
// handling one, and nothing has set it yet at init time.
|
// handling one, and nothing has set it yet at init time.
|
||||||
for (uint8_t i = 0; i < UIP_CONNS; i++)
|
for (uint8_t i = 0; i < UIP_CONNS; i++)
|
||||||
uip_conns[i].appstate.tstate = TSTATE_CLOSED;
|
uip_conns[i].appstate.tstate = TSTATE_CLOSED;
|
||||||
|
session_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -343,38 +343,11 @@ __xdata uint8_t *scan_header(__xdata uint8_t * __xdata p)
|
|||||||
|
|
||||||
read_reg_timer(&now);
|
read_reg_timer(&now);
|
||||||
|
|
||||||
if (session && session_id[0]) {
|
if (session)
|
||||||
if (now - last_session_use > session_timeout) {
|
session_check();
|
||||||
dbg_string("Session expired\n");
|
|
||||||
} else {
|
|
||||||
if (is_word_x(session, session_id)) {
|
|
||||||
authenticated = 1;
|
|
||||||
last_session_use = now;
|
|
||||||
} else {
|
|
||||||
dbg_string("Invalid session cookie!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Generate random HEX-chars at the buffer location.
|
|
||||||
*/
|
|
||||||
void gen_random_hex_chars(__xdata uint8_t * b, __xdata uint8_t bytes)
|
|
||||||
{
|
|
||||||
uint8_t i = 0;
|
|
||||||
while (bytes) {
|
|
||||||
if (!i)
|
|
||||||
get_random_32();
|
|
||||||
b[--bytes] = itohex(sfr_data[i]);
|
|
||||||
if (!bytes) { break; }
|
|
||||||
b[--bytes] = itohex(sfr_data[i] >> 4 | sfr_data[i] << 4);
|
|
||||||
i = (i + 1) & 0x3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 0: body incomplete, 1: configuration stored, 2: malformed */
|
/* 0: body incomplete, 1: configuration stored, 2: malformed */
|
||||||
static uint8_t config_take(void)
|
static uint8_t config_take(void)
|
||||||
{
|
{
|
||||||
@@ -531,9 +504,10 @@ uint8_t stream_upload(void)
|
|||||||
memcpy(flash_buf + write_len, boundary, bindex);
|
memcpy(flash_buf + write_len, boundary, bindex);
|
||||||
write_len += bindex;
|
write_len += bindex;
|
||||||
bindex = 0;
|
bindex = 0;
|
||||||
}
|
} else {
|
||||||
crc16_bank1(upload_settings.p + upload_settings.bptr);
|
crc16_bank1(upload_settings.p + upload_settings.bptr);
|
||||||
flash_buf[write_len++] = upload_settings.p[upload_settings.bptr++];
|
flash_buf[write_len++] = upload_settings.p[upload_settings.bptr++];
|
||||||
|
}
|
||||||
if (write_len >= FLASH_PAGE_SIZE) {
|
if (write_len >= FLASH_PAGE_SIZE) {
|
||||||
/* The staged image spans FIRMWARE_UPLOAD_START to twice that,
|
/* The staged image spans FIRMWARE_UPLOAD_START to twice that,
|
||||||
* the span check_and_flash_update_image() reads back. Nothing
|
* the span check_and_flash_update_image() reads back. Nothing
|
||||||
@@ -565,7 +539,6 @@ uint8_t stream_upload(void)
|
|||||||
memcpy(flash_buf, flash_buf + FLASH_PAGE_SIZE, write_len);
|
memcpy(flash_buf, flash_buf + FLASH_PAGE_SIZE, write_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bindex = 0;
|
|
||||||
}
|
}
|
||||||
} while(1);
|
} while(1);
|
||||||
}
|
}
|
||||||
@@ -675,13 +648,10 @@ static void run_login_body(__xdata uint8_t *body)
|
|||||||
{
|
{
|
||||||
if (strstart(body, "pwd=") && is_url_word_x(body + 4, passwd)) {
|
if (strstart(body, "pwd=") && is_url_word_x(body + 4, passwd)) {
|
||||||
dbg_string("Password accepted!\n");
|
dbg_string("Password accepted!\n");
|
||||||
read_reg_timer(&last_session_use);
|
read_reg_timer(&now);
|
||||||
gen_random_hex_chars(session_id, SESSION_ID_LENGTH);
|
|
||||||
session_id[SESSION_ID_LENGTH] = NUL;
|
|
||||||
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nConnection: close\r\nLocation: index.html\r\n" \
|
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nConnection: close\r\nLocation: index.html\r\n" \
|
||||||
"Set-Cookie: session=");
|
"Set-Cookie: session=");
|
||||||
for (uint8_t i = 0; i < SESSION_ID_LENGTH; i++)
|
session_new();
|
||||||
outbuf[slen++] = session_id[i];
|
|
||||||
slen += strtox(outbuf + slen, "; SameSite=Strict\r\n\r\n");
|
slen += strtox(outbuf + slen, "; SameSite=Strict\r\n\r\n");
|
||||||
} else {
|
} else {
|
||||||
dbg_string("Password invalid!\n");
|
dbg_string("Password invalid!\n");
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
MACHINE_COMMON_SETTING,
|
||||||
|
.mac_flash_offset = 0x1FC000,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO38,
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO48_I2C_SCL1,
|
||||||
|
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.led_mux = { 0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0c, 0x09, 0x0d, 0x10, 0x11, 0x0e, 0x14, 0x11, 0x12, 0x15, 0x15, 0x16, 0x18, 0x19, 0x1a, 0x19, 0x1d, 0x1e, 0x1c, 0x1d, 0x20, 0x21 },
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_DUPLEX,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT
|
||||||
|
},
|
||||||
|
{ LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_10G | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_COL | LEDS_DUPLEX
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "machine_init_defs.h"
|
||||||
|
|
||||||
|
void machine_custom_init(void) __banked
|
||||||
|
{
|
||||||
|
REG_SET(RTL837X_REG_LED_GLB_IO_EN, 0x7f24977f);
|
||||||
|
}
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
PCB_AFGW_SWTG218ANS_V_2_0_2.c
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _MACHINE_SWTG218ANS_V_2_0_2_H_
|
||||||
|
#define _MACHINE_SWTG218ANS_V_2_0_2_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "RealHD PSW8-25MG"
|
||||||
|
#define MACHINE_CHIPSET RTL8373
|
||||||
|
|
||||||
|
#endif
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
PCB_AFGW_SWTG218ANS_V_2_0_2_init.c
|
||||||
@@ -154,6 +154,7 @@ void print_long(uint32_t a);
|
|||||||
void print_short(uint16_t a);
|
void print_short(uint16_t a);
|
||||||
void print_byte(uint8_t a);
|
void print_byte(uint8_t a);
|
||||||
void itoa(uint8_t v);
|
void itoa(uint8_t v);
|
||||||
|
void itoa_no_syslog(uint8_t v);
|
||||||
void itoa_short(uint16_t v);
|
void itoa_short(uint16_t v);
|
||||||
void print_sfr_data(void);
|
void print_sfr_data(void);
|
||||||
void print_phy_data(void);
|
void print_phy_data(void);
|
||||||
|
|||||||
+4
-2
@@ -221,9 +221,11 @@ void rtl8372_init(void) __banked
|
|||||||
} else if(machine.n_10g == 2) {
|
} else if(machine.n_10g == 2) {
|
||||||
REG_SET(RTL837X_REG_SDS_MODES, 0x1ad); // Both 10g ports use SDS_QXGMII
|
REG_SET(RTL837X_REG_SDS_MODES, 0x1ad); // Both 10g ports use SDS_QXGMII
|
||||||
} else {
|
} else {
|
||||||
|
// Replace the reset value 0xbff (both SDS off) instead of ORing into it:
|
||||||
|
// RTL837X_REG_SEC_COUNTER only holds a written value while SDS 0 is on
|
||||||
reg_read_m(RTL837X_REG_SDS_MODES);
|
reg_read_m(RTL837X_REG_SDS_MODES);
|
||||||
sfr_mask_data(1, 0, 0x03);
|
sfr_mask_data(1, 0xff, 0x03);
|
||||||
sfr_mask_data(0, 0, 0xe2);
|
sfr_mask_data(0, 0xff, 0xe2);
|
||||||
reg_write_m(RTL837X_REG_SDS_MODES);
|
reg_write_m(RTL837X_REG_SDS_MODES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -271,7 +271,7 @@ void vlan_setup(void) __banked
|
|||||||
wait_table_ready();
|
wait_table_ready();
|
||||||
|
|
||||||
// Set PVID 1 for every port. TODO: Skip unused ports!
|
// Set PVID 1 for every port. TODO: Skip unused ports!
|
||||||
for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT + 1; i++) { // Do this also for the CPU port (+1)
|
for (uint8_t i = MACHINE_MIN_PORT; i <= CPU_PORT; i++) { // CPU MAC is independent of the last user port
|
||||||
uint16_t reg = RTL837x_PVID_BASE_REG + ((i >> 1) << 2);
|
uint16_t reg = RTL837x_PVID_BASE_REG + ((i >> 1) << 2);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_byte(i); write_char(':'); write_char(' '); print_short(reg); write_char('=');
|
print_byte(i); write_char(':'); write_char(' '); print_short(reg); write_char('=');
|
||||||
@@ -307,7 +307,7 @@ void vlan_setup(void) __banked
|
|||||||
REG_SET(RTL837X_VLAN_L2_LRN_DIS_0, 0);
|
REG_SET(RTL837X_VLAN_L2_LRN_DIS_0, 0);
|
||||||
REG_SET(RTL837X_VLAN_L2_LRN_DIS_1, 0);
|
REG_SET(RTL837X_VLAN_L2_LRN_DIS_1, 0);
|
||||||
|
|
||||||
// Enable VLAN 1: Ports 0-9, i.e. including the CPU port are untagged members
|
// Enable VLAN 1: user ports untagged, CPU MAC9 tagged (untag bit 19 clear)
|
||||||
REG_SET(RTL837x_TBL_DATA_IN_A, machine_detected.isRTL8373? 0x0207ffff : 0x0207e3f8); // 02: Entry valid, 7...: membership
|
REG_SET(RTL837x_TBL_DATA_IN_A, machine_detected.isRTL8373? 0x0207ffff : 0x0207e3f8); // 02: Entry valid, 7...: membership
|
||||||
|
|
||||||
REG_SET(RTL837X_TBL_CTRL, 0x00010303); // Write VLAN 1
|
REG_SET(RTL837X_TBL_CTRL, 0x00010303); // Write VLAN 1
|
||||||
|
|||||||
@@ -305,6 +305,19 @@ void itoa(uint8_t v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void itoa_no_syslog(uint8_t v)
|
||||||
|
{
|
||||||
|
uint8_t t = (v / 100);
|
||||||
|
uint8_t print_zeros = t;
|
||||||
|
if (print_zeros)
|
||||||
|
write_char_no_syslog('0' + t);
|
||||||
|
t = (v / 10) % 10;
|
||||||
|
print_zeros |= t;
|
||||||
|
if (print_zeros)
|
||||||
|
write_char_no_syslog('0' + t);
|
||||||
|
write_char_no_syslog('0' + (v % 10));
|
||||||
|
}
|
||||||
|
|
||||||
/* Same as itoa(), one decade wider: enough for a port number. Kept separate
|
/* Same as itoa(), one decade wider: enough for a port number. Kept separate
|
||||||
* rather than widening itoa() itself, because every existing caller passes a
|
* rather than widening itoa() itself, because every existing caller passes a
|
||||||
* byte and would start paying for 16-bit divisions it does not need. */
|
* byte and would start paying for 16-bit divisions it does not need. */
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
https://sourceforge.net/p/sdcc/bugs/4153/
|
||||||
|
|
||||||
|
Index: src/mcs51/ralloc.c
|
||||||
|
===================================================================
|
||||||
|
--- src/mcs51/ralloc.c (revision 17011)
|
||||||
|
+++ src/mcs51/ralloc.c (working copy)
|
||||||
|
@@ -1208,7 +1208,7 @@
|
||||||
|
int change = 0;
|
||||||
|
|
||||||
|
/* if the result has been spilt then cannot share */
|
||||||
|
- if (opsym->isspilt)
|
||||||
|
+ if (result->isspilt || opsym->isspilt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
https://sourceforge.net/p/sdcc/bugs/4154/
|
||||||
|
|
||||||
|
Index: src/mcs51/ralloc.c
|
||||||
|
===================================================================
|
||||||
|
--- src/mcs51/ralloc.c (revision 17011)
|
||||||
|
+++ src/mcs51/ralloc.c (working copy)
|
||||||
|
@@ -641,6 +641,7 @@
|
||||||
|
spillThis (symbol * sym)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
+ bool ownsRegs = bitVectBitValue (_G.regAssigned, sym->key);
|
||||||
|
/* if this is rematerializable or has a spillLocation
|
||||||
|
we are okay, else we need to create a spillLocation
|
||||||
|
for it */
|
||||||
|
@@ -658,7 +659,8 @@
|
||||||
|
{
|
||||||
|
if (sym->regs[i])
|
||||||
|
{
|
||||||
|
- freeReg (sym->regs[i]);
|
||||||
|
+ if (ownsRegs)
|
||||||
|
+ freeReg (sym->regs[i]);
|
||||||
|
sym->regs[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
https://sourceforge.net/p/sdcc/bugs/4070/
|
||||||
|
|
||||||
|
Index: sdas/asxxsrc/asexpr.c
|
||||||
|
===================================================================
|
||||||
|
--- sdas/asxxsrc/asexpr.c
|
||||||
|
+++ sdas/asxxsrc/asexpr.c
|
||||||
|
@@ -863,18 +863,59 @@
|
||||||
|
return((n & s_mask) ? (n | ~v_mask) : (n & v_mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
-/*)Function void exprmasks(esp)
|
||||||
|
+/*)Function void exprmasks(n)
|
||||||
|
*
|
||||||
|
* int n T Line Bytes in Address
|
||||||
|
*
|
||||||
|
* The function exprmasks() configures the assembler
|
||||||
|
- * for 16, 24, or 32-Bit Data/Addresses.
|
||||||
|
+ * for 16, 24, or 32-Bit Data/Addresses. The arithmetic
|
||||||
|
+ * precision follows the address width unless a port
|
||||||
|
+ * calls valmasks() afterwards.
|
||||||
|
*
|
||||||
|
* local variables:
|
||||||
|
* none
|
||||||
|
*
|
||||||
|
* global variables:
|
||||||
|
* int a_bytes T Line Bytes in Address
|
||||||
|
+ *
|
||||||
|
+ * functions called:
|
||||||
|
+ * void valmasks() asexpr.c
|
||||||
|
+ *
|
||||||
|
+ * side effects:
|
||||||
|
+ * The address width and arithmetic precision
|
||||||
|
+ * parameters are set.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+exprmasks(int n)
|
||||||
|
+{
|
||||||
|
+ switch(n) {
|
||||||
|
+ default:
|
||||||
|
+ n = 2;
|
||||||
|
+ case 2:
|
||||||
|
+ case 3:
|
||||||
|
+ case 4:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ a_bytes = n;
|
||||||
|
+ valmasks(n);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*)Function void valmasks(n)
|
||||||
|
+ *
|
||||||
|
+ * int n Bytes of arithmetic precision
|
||||||
|
+ *
|
||||||
|
+ * The function valmasks() configures the 16, 24, or
|
||||||
|
+ * 32-Bit arithmetic precision independently of the
|
||||||
|
+ * T Line address width. A port whose addresses fit
|
||||||
|
+ * in 24 bits but whose symbols may hold 32-bit values
|
||||||
|
+ * (the 8051 __sfr32 address lists, for example) uses
|
||||||
|
+ * exprmasks(3) followed by valmasks(4).
|
||||||
|
+ *
|
||||||
|
+ * local variables:
|
||||||
|
+ * none
|
||||||
|
+ *
|
||||||
|
+ * global variables:
|
||||||
|
* a_uint a_mask Address mask
|
||||||
|
* a_uint s_mask Sign mask
|
||||||
|
* a_uint v_mask Value mask
|
||||||
|
@@ -885,16 +926,13 @@
|
||||||
|
* side effects:
|
||||||
|
* The arithmetic precision parameters are set.
|
||||||
|
*/
|
||||||
|
-
|
||||||
|
+
|
||||||
|
void
|
||||||
|
-exprmasks(int n)
|
||||||
|
+valmasks(int n)
|
||||||
|
{
|
||||||
|
- a_bytes = n;
|
||||||
|
-
|
||||||
|
#ifdef LONGINT
|
||||||
|
- switch(a_bytes) {
|
||||||
|
+ switch(n) {
|
||||||
|
default:
|
||||||
|
- a_bytes = 2;
|
||||||
|
case 2:
|
||||||
|
a_mask = (a_uint) 0x0000FFFFl;
|
||||||
|
s_mask = (a_uint) 0x00008000l;
|
||||||
|
@@ -914,9 +952,8 @@
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
- switch(a_bytes) {
|
||||||
|
+ switch(n) {
|
||||||
|
default:
|
||||||
|
- a_bytes = 2;
|
||||||
|
case 2:
|
||||||
|
a_mask = (a_uint) 0x0000FFFF;
|
||||||
|
s_mask = (a_uint) 0x00008000;
|
||||||
|
Index: sdas/asxxsrc/asxxxx.h
|
||||||
|
===================================================================
|
||||||
|
--- sdas/asxxsrc/asxxxx.h
|
||||||
|
+++ sdas/asxxsrc/asxxxx.h
|
||||||
|
@@ -1354,6 +1354,7 @@
|
||||||
|
extern int digit(int c, int r);
|
||||||
|
extern int is_digit(int c, int r);
|
||||||
|
extern void exprmasks(int n);
|
||||||
|
+extern void valmasks(int n);
|
||||||
|
extern void expr(struct expr *esp, int n);
|
||||||
|
extern void binop(int c, struct expr *esp, struct expr *re);
|
||||||
|
extern int is_abs(struct expr *esp);
|
||||||
|
Index: sdas/as8051/i51mch.c
|
||||||
|
===================================================================
|
||||||
|
--- sdas/as8051/i51mch.c
|
||||||
|
+++ sdas/as8051/i51mch.c
|
||||||
|
@@ -782,9 +782,12 @@
|
||||||
|
hilo = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Address Space
|
||||||
|
+ * Address Space: 24-bit addresses in the T lines,
|
||||||
|
+ * 32-bit arithmetic so that __sfr32 address lists
|
||||||
|
+ * like 0xa4a5a6a7 keep their most significant byte.
|
||||||
|
*/
|
||||||
|
- exprmasks(3);
|
||||||
|
+ exprmasks(3);
|
||||||
|
+ valmasks(4);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First time only:
|
||||||
Executable
+26
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
V=4.6.0
|
||||||
|
SHA=5fd6a93e5997ce01756868fe35e441095cfb637894a80c262514a634094973b6
|
||||||
|
PREFIX=$1
|
||||||
|
D=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
W=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$W"' EXIT
|
||||||
|
curl -fL -o "$W/sdcc.tar.bz2" "https://downloads.sourceforge.net/project/sdcc/sdcc/$V/sdcc-src-$V.tar.bz2"
|
||||||
|
if command -v sha256sum >/dev/null; then
|
||||||
|
echo "$SHA $W/sdcc.tar.bz2" | sha256sum -c -
|
||||||
|
else
|
||||||
|
echo "$SHA $W/sdcc.tar.bz2" | shasum -a 256 -c -
|
||||||
|
fi
|
||||||
|
tar -C "$W" -xjf "$W/sdcc.tar.bz2"
|
||||||
|
cd "$W/sdcc-$V"
|
||||||
|
for p in "$D"/*.patch; do
|
||||||
|
patch -p0 < "$p"
|
||||||
|
done
|
||||||
|
off=""
|
||||||
|
for p in z80 z180 r2k r2ka r3ka r4k r5k r6k sm83 tlcs90 ez80 ez80_z80 z80n r800 ds390 ds400 pic14 pic16 hc08 s08 stm8 pdk13 pdk14 pdk15 mos6502 mos65c02 huc6280 f8 f8l; do
|
||||||
|
off="$off --disable-$p-port"
|
||||||
|
done
|
||||||
|
./configure --prefix="$PREFIX" $off --disable-sdcdb --disable-ucsim --disable-non-free
|
||||||
|
make -j"$(getconf _NPROCESSORS_ONLN)"
|
||||||
|
make install
|
||||||
+128
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* Login sessions of the web interface.
|
||||||
|
*
|
||||||
|
* Up to SESSIONS logins at once, each with its own cookie and its own expiry.
|
||||||
|
* With a single one, logging in from a second browser (or a phone) ended the
|
||||||
|
* first browser's session at its next request.
|
||||||
|
*
|
||||||
|
* This sits in bank 3: the web server's own bank is full, so httpd.c only
|
||||||
|
* calls in here. It shares three things with httpd.c: the cookie value it
|
||||||
|
* parsed (session), the time read for the request (now) and the result
|
||||||
|
* (authenticated); the reply is written to outbuf at slen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma codeseg BANK3
|
||||||
|
#pragma constseg BANK3
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "sessions.h"
|
||||||
|
|
||||||
|
extern volatile __xdata uint8_t sfr_data[4];
|
||||||
|
extern __xdata uint16_t session_timeout;
|
||||||
|
extern __xdata uint32_t now;
|
||||||
|
extern __xdata uint8_t authenticated;
|
||||||
|
extern __xdata uint8_t * __xdata session;
|
||||||
|
extern __xdata uint8_t outbuf[];
|
||||||
|
extern __xdata uint16_t slen;
|
||||||
|
|
||||||
|
__xdata char session_id[SESSIONS][SESSION_ID_LENGTH + 1];
|
||||||
|
__xdata uint32_t last_session_use[SESSIONS];
|
||||||
|
|
||||||
|
static __xdata uint8_t ss_slot, ss_i, ss_oldest, ss_c;
|
||||||
|
/* The slot whose cookie the last request came with; only meaningful while
|
||||||
|
* authenticated is set, which only session_check() does */
|
||||||
|
static __xdata uint8_t ss_hit;
|
||||||
|
|
||||||
|
static __code const char ss_hex[] = "0123456789abcdef";
|
||||||
|
/* What may follow a cookie value: ';' separates cookies in a Cookie header */
|
||||||
|
static __code const char ss_end[] = " \t:?=\n\r;";
|
||||||
|
|
||||||
|
/* Leaf function, so the compiler keeps its 32-bit scratch in the overlay
|
||||||
|
* rather than in internal RAM. */
|
||||||
|
static uint8_t ss_stale(void)
|
||||||
|
{
|
||||||
|
if (now - last_session_use[ss_slot] > session_timeout)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Likewise a leaf: the 32-bit comparison needs no stack of its own this way */
|
||||||
|
static uint8_t ss_older(void)
|
||||||
|
{
|
||||||
|
if (last_session_use[ss_slot] < last_session_use[ss_oldest])
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Whether the cookie value is the id of slot ss_slot */
|
||||||
|
static uint8_t ss_match(void)
|
||||||
|
{
|
||||||
|
for (ss_i = 0; ss_i < SESSION_ID_LENGTH; ss_i++) {
|
||||||
|
if (session[ss_i] != session_id[ss_slot][ss_i])
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ss_c = session[SESSION_ID_LENGTH];
|
||||||
|
if (!ss_c)
|
||||||
|
return 1;
|
||||||
|
for (ss_i = 0; ss_end[ss_i]; ss_i++) {
|
||||||
|
if (ss_c == ss_end[ss_i])
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void session_init(void) __banked
|
||||||
|
{
|
||||||
|
for (ss_slot = 0; ss_slot < SESSIONS; ss_slot++)
|
||||||
|
session_id[ss_slot][0] = NUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void session_check(void) __banked
|
||||||
|
{
|
||||||
|
for (ss_slot = 0; ss_slot < SESSIONS; ss_slot++) {
|
||||||
|
if (!session_id[ss_slot][0])
|
||||||
|
continue;
|
||||||
|
if (ss_stale()) {
|
||||||
|
session_id[ss_slot][0] = NUL;
|
||||||
|
} else if (ss_match()) {
|
||||||
|
authenticated = 1;
|
||||||
|
ss_hit = ss_slot;
|
||||||
|
last_session_use[ss_slot] = now;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void session_new(void) __banked
|
||||||
|
{
|
||||||
|
if (authenticated && session_id[ss_hit][0]) {
|
||||||
|
/* The login came with a cookie that is still valid: its slot gets the
|
||||||
|
* new id. A second slot for the same browser would leave the old one
|
||||||
|
* looking fresh and push out someone else at the next login. */
|
||||||
|
ss_slot = ss_hit;
|
||||||
|
} else {
|
||||||
|
/* A free or expired slot, else the least recently used */
|
||||||
|
ss_oldest = 0;
|
||||||
|
for (ss_slot = 0; ss_slot < SESSIONS; ss_slot++) {
|
||||||
|
if (!session_id[ss_slot][0] || ss_stale())
|
||||||
|
break;
|
||||||
|
if (ss_older())
|
||||||
|
ss_oldest = ss_slot;
|
||||||
|
}
|
||||||
|
if (ss_slot == SESSIONS)
|
||||||
|
ss_slot = ss_oldest;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_session_use[ss_slot] = now;
|
||||||
|
for (ss_i = 0; ss_i < SESSION_ID_LENGTH; ss_i++) {
|
||||||
|
if (!(ss_i & 7))
|
||||||
|
get_random_32();
|
||||||
|
ss_c = sfr_data[(ss_i >> 1) & 3];
|
||||||
|
if (ss_i & 1)
|
||||||
|
ss_c >>= 4;
|
||||||
|
session_id[ss_slot][ss_i] = ss_hex[ss_c & 0xf];
|
||||||
|
outbuf[slen++] = ss_hex[ss_c & 0xf];
|
||||||
|
}
|
||||||
|
session_id[ss_slot][SESSION_ID_LENGTH] = NUL;
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef _SESSIONS_H_
|
||||||
|
#define _SESSIONS_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define SESSIONS 4
|
||||||
|
#define SESSION_ID_LENGTH 12
|
||||||
|
|
||||||
|
extern __xdata char session_id[SESSIONS][SESSION_ID_LENGTH + 1];
|
||||||
|
extern __xdata uint32_t last_session_use[SESSIONS];
|
||||||
|
|
||||||
|
/* No session at boot */
|
||||||
|
void session_init(void) __banked;
|
||||||
|
/* Sets authenticated if the cookie in session belongs to a live session */
|
||||||
|
void session_check(void) __banked;
|
||||||
|
/* Starts a session at now and writes its id to outbuf at slen */
|
||||||
|
void session_new(void) __banked;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -29,6 +29,9 @@ TESTS = $(BUILDDIR)/test_cmd_editor \
|
|||||||
$(BUILDDIR)/test_page_json \
|
$(BUILDDIR)/test_page_json \
|
||||||
$(BUILDDIR)/test_httpd_tx \
|
$(BUILDDIR)/test_httpd_tx \
|
||||||
$(BUILDDIR)/test_tick_gate \
|
$(BUILDDIR)/test_tick_gate \
|
||||||
|
$(BUILDDIR)/test_cpu_vlan_full \
|
||||||
|
$(BUILDDIR)/test_cpu_vlan_restricted \
|
||||||
|
$(BUILDDIR)/test_cpu_vlan_8372 \
|
||||||
$(BUILDDIR)/test_nic_rx \
|
$(BUILDDIR)/test_nic_rx \
|
||||||
$(BUILDDIR)/test_lacp
|
$(BUILDDIR)/test_lacp
|
||||||
|
|
||||||
@@ -69,6 +72,14 @@ $(BUILDDIR)/test_lacp: test_lacp.c $(SRCROOT)/rtl837x_lacp.c | $(BUILDDIR)
|
|||||||
# this test carries the environment below them itself.
|
# this test carries the environment below them itself.
|
||||||
$(BUILDDIR)/test_httpd_tx: test_httpd_tx.c $(SRCROOT)/httpd/httpd.c $(SRCROOT)/uip/uip.c | $(BUILDDIR)
|
$(BUILDDIR)/test_httpd_tx: test_httpd_tx.c $(SRCROOT)/httpd/httpd.c $(SRCROOT)/uip/uip.c | $(BUILDDIR)
|
||||||
$(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS)
|
||||||
|
# the login sessions httpd.c calls into
|
||||||
|
$(BUILDDIR)/test_httpd_tx: $(SRCROOT)/sessions.c
|
||||||
|
|
||||||
|
# CPU VLAN initialization with full and reduced user-port ranges.
|
||||||
|
$(BUILDDIR)/test_cpu_vlan_restricted: CFLAGS += -DMACHINE_MAX_PORT=7
|
||||||
|
$(BUILDDIR)/test_cpu_vlan_8372: CFLAGS += -DMACHINE_MAX_PORT=7 -DMACHINE_MIN_PORT=3 -DRTLP_TEST_IS8373=0
|
||||||
|
$(BUILDDIR)/test_cpu_vlan_full $(BUILDDIR)/test_cpu_vlan_restricted $(BUILDDIR)/test_cpu_vlan_8372: test_cpu_vlan.c $(TABLE_ENV) | $(BUILDDIR)
|
||||||
|
$(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
run: $(TESTS)
|
run: $(TESTS)
|
||||||
@fail=0; for t in $(TESTS); do \
|
@fail=0; for t in $(TESTS); do \
|
||||||
|
|||||||
+4
-1
@@ -57,13 +57,16 @@ const uint8_t hex_chars[] = "0123456789abcdef";
|
|||||||
uint8_t *hex = (uint8_t *)hex_chars;
|
uint8_t *hex = (uint8_t *)hex_chars;
|
||||||
|
|
||||||
/* ---- a 9-port RTL8373 whose logical ports map to themselves ---- */
|
/* ---- a 9-port RTL8373 whose logical ports map to themselves ---- */
|
||||||
|
#ifndef RTLP_TEST_IS8373
|
||||||
|
#define RTLP_TEST_IS8373 1
|
||||||
|
#endif
|
||||||
const struct machine machine = {
|
const struct machine machine = {
|
||||||
.machine_name = "HOSTTEST",
|
.machine_name = "HOSTTEST",
|
||||||
.n_sfp = 0,
|
.n_sfp = 0,
|
||||||
.log_to_phys_port = { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
|
.log_to_phys_port = { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
|
||||||
.phys_to_log_port = { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
|
.phys_to_log_port = { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
|
||||||
};
|
};
|
||||||
struct machine_runtime machine_detected = { .isRTL8373 = 1 };
|
struct machine_runtime machine_detected = { .isRTL8373 = RTLP_TEST_IS8373 };
|
||||||
|
|
||||||
/* ---- firmware state the modules read or write ---- */
|
/* ---- firmware state the modules read or write ---- */
|
||||||
uint8_t outbuf[TCP_OUTBUF_SIZE];
|
uint8_t outbuf[TCP_OUTBUF_SIZE];
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "rtl837x_port.h"
|
||||||
|
#include "machine.h"
|
||||||
|
#include "support.h"
|
||||||
|
#include "hw_mock.h"
|
||||||
|
extern const struct machine machine;
|
||||||
|
extern struct machine_runtime machine_detected;
|
||||||
|
int main(void) {
|
||||||
|
hw_reset();out_reset();
|
||||||
|
hw_reg_set(RTL837X_VLAN_PORT_EGR_TAG,0xa50fffff);
|
||||||
|
hw_reg_set(RTL837x_PVID_BASE_REG+16,0x5a123456);
|
||||||
|
vlan_setup();
|
||||||
|
uint32_t untouched=(1u<<(MACHINE_MIN_PORT*2))-1;
|
||||||
|
CHECK(hw_reg_get(RTL837X_VLAN_PORT_EGR_TAG)==(0xa5000000|untouched),"CPU egress set, unrelated bits preserved");
|
||||||
|
CHECK(hw_reg_get(RTL837x_PVID_BASE_REG+16)==0x5a001001,"CPU PVID initialized explicitly");
|
||||||
|
uint16_t active=((1u<<(MACHINE_MAX_PORT+1))-1)&~((1u<<MACHINE_MIN_PORT)-1);
|
||||||
|
CHECK(hw_reg_get(RTL837X_VLAN_PORT_IGR_FLTR)==(active|PMASK_CPU),"CPU ingress included, excluded user ports rejected");
|
||||||
|
CHECK(hw_vlan_word(1)==(machine_detected.isRTL8373?0x0207ffff:0x0207e3f8),"existing family VLAN membership preserved");
|
||||||
|
CHECK(hw_vlan_word(2)==0,"no unrelated VLAN changed");
|
||||||
|
printf("CPU VLAN min=%u max=%u RTL8373=%u: %d checks, %d failed\n",MACHINE_MIN_PORT,MACHINE_MAX_PORT,machine_detected.isRTL8373,tests_run,tests_failed);
|
||||||
|
return tests_failed?1:0;
|
||||||
|
}
|
||||||
+194
-5
@@ -81,7 +81,7 @@ static uint8_t written_config[CONFIG_LEN];
|
|||||||
static uint16_t written_config_len;
|
static uint16_t written_config_len;
|
||||||
static uint32_t config_erase_addr, config_write_addr;
|
static uint32_t config_erase_addr, config_write_addr;
|
||||||
static int config_erases, config_writes;
|
static int config_erases, config_writes;
|
||||||
static uint8_t flash_written[64];
|
static uint8_t flash_written[1024];
|
||||||
static size_t flash_written_len;
|
static size_t flash_written_len;
|
||||||
static int flash_write_bad;
|
static int flash_write_bad;
|
||||||
|
|
||||||
@@ -132,7 +132,9 @@ void reset_chip(void) { reset_calls++; }
|
|||||||
void delay(uint16_t t) { (void)t; }
|
void delay(uint16_t t) { (void)t; }
|
||||||
void write_char(char c) { (void)c; }
|
void write_char(char c) { (void)c; }
|
||||||
void write_char_no_syslog(char c) { (void)c; }
|
void write_char_no_syslog(char c) { (void)c; }
|
||||||
|
void itoa_no_syslog(uint8_t v) { (void)v; }
|
||||||
void print_string(const char *p) { (void)p; }
|
void print_string(const char *p) { (void)p; }
|
||||||
|
void print_string_no_syslog(const char *p) { (void)p; }
|
||||||
void print_string_newline_no_syslog(const char *p) { (void)p; }
|
void print_string_newline_no_syslog(const char *p) { (void)p; }
|
||||||
void set_sys_led_state(uint8_t state) { (void)state; }
|
void set_sys_led_state(uint8_t state) { (void)state; }
|
||||||
void cmd_parser(void) { }
|
void cmd_parser(void) { }
|
||||||
@@ -142,7 +144,8 @@ void clear_command_history(void) { }
|
|||||||
void udp_callbacks(void) { }
|
void udp_callbacks(void) { }
|
||||||
void tcpip_output(void) { }
|
void tcpip_output(void) { }
|
||||||
void get_random_32(void) { }
|
void get_random_32(void) { }
|
||||||
void read_reg_timer(uint32_t *tmr) { *tmr = 0; }
|
static uint32_t fake_now;
|
||||||
|
void read_reg_timer(uint32_t *tmr) { *tmr = fake_now; }
|
||||||
|
|
||||||
/* uip-conf.h asks uIP not to define the packet buffer: on the switch it lives
|
/* uip-conf.h asks uIP not to define the packet buffer: on the switch it lives
|
||||||
* at a fixed XDATA address, so the bench provides the storage itself. */
|
* at a fixed XDATA address, so the bench provides the storage itself. */
|
||||||
@@ -191,9 +194,9 @@ void send_lldp(void) {}
|
|||||||
|
|
||||||
extern uint8_t authenticated;
|
extern uint8_t authenticated;
|
||||||
extern char session_id[];
|
extern char session_id[];
|
||||||
|
extern uint32_t last_session_use[];
|
||||||
extern char passwd[21];
|
extern char passwd[21];
|
||||||
extern uint16_t session_timeout;
|
extern uint16_t session_timeout;
|
||||||
extern uint32_t last_session_use;
|
|
||||||
|
|
||||||
/* uip.c defines the listen table but no header declares it; the bench reads it
|
/* uip.c defines the listen table but no header declares it; the bench reads it
|
||||||
* to confirm the port httpd_init() asked for is the one uIP is watching. */
|
* to confirm the port httpd_init() asked for is the one uIP is watching. */
|
||||||
@@ -549,7 +552,7 @@ static void scenario_bad_l4_checksum(void)
|
|||||||
|
|
||||||
|
|
||||||
/* Private HTTP lifecycle values; drive the real callback, not a model. */
|
/* Private HTTP lifecycle values; drive the real callback, not a model. */
|
||||||
enum { TSTATE_NONE = 0, TSTATE_TX = 1 };
|
enum { TSTATE_NONE = 0, TSTATE_TX = 1, TSTATE_POST = 4 };
|
||||||
extern uint16_t slen, cont_len, sent_len, bindex, crc_final, write_len;
|
extern uint16_t slen, cont_len, sent_len, bindex, crc_final, write_len;
|
||||||
extern uint8_t boundary[], verify_crc, outbuf[];
|
extern uint8_t boundary[], verify_crc, outbuf[];
|
||||||
extern struct { uint8_t *p; uint16_t bptr, plen; } upload_settings;
|
extern struct { uint8_t *p; uint16_t bptr, plen; } upload_settings;
|
||||||
@@ -877,6 +880,77 @@ static void scenario_split_get_header_terminator(void)
|
|||||||
"fragmented GET terminator: CRLFCRLF may span receive events");
|
"fragmented GET terminator: CRLFCRLF may span receive events");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The sessions of the login tests below: four in use, slot 1 the least recently used */
|
||||||
|
#define ID_STRIDE 13 /* SESSION_ID_LENGTH + 1 */
|
||||||
|
|
||||||
|
static const char *slot_id(int i)
|
||||||
|
{
|
||||||
|
return session_id + i * ID_STRIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_sessions(void)
|
||||||
|
{
|
||||||
|
static const char *const ids[4] = { "0123456789ab", "aaaaaaaaaaaa", "bbbbbbbbbbbb", "cccccccccccc" };
|
||||||
|
static const uint32_t used[4] = { 50, 10, 60, 70 };
|
||||||
|
|
||||||
|
fake_now = 100;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
strcpy(session_id + i * ID_STRIDE, ids[i]);
|
||||||
|
last_session_use[i] = used[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int others_kept(int first, int second, int third)
|
||||||
|
{
|
||||||
|
static const char *const ids[4] = { "0123456789ab", "aaaaaaaaaaaa", "bbbbbbbbbbbb", "cccccccccccc" };
|
||||||
|
|
||||||
|
return !strcmp(slot_id(first), ids[first]) && !strcmp(slot_id(second), ids[second]) &&
|
||||||
|
!strcmp(slot_id(third), ids[third]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scenario_login_with_valid_cookie_reuses_its_slot(void)
|
||||||
|
{
|
||||||
|
static const char post[] =
|
||||||
|
"POST /login HTTP/1.1\r\n"
|
||||||
|
"Cookie: session=0123456789ab\r\n"
|
||||||
|
"Content-Length: 8\r\n"
|
||||||
|
"Content-Type: application/x-www-form-urlencoded\r\n"
|
||||||
|
"\r\n"
|
||||||
|
"pwd=1234";
|
||||||
|
|
||||||
|
login_session_start();
|
||||||
|
fill_sessions();
|
||||||
|
client_send(TCP_ACK | TCP_PSH, post, (int)strlen(post));
|
||||||
|
CHECK(stream_contains("Location: index.html\r\n"),
|
||||||
|
"login with a valid cookie: accepted");
|
||||||
|
CHECK(strcmp(slot_id(0), "0123456789ab") != 0,
|
||||||
|
"login with a valid cookie: its own slot gets the new id");
|
||||||
|
CHECK(others_kept(1, 2, 3),
|
||||||
|
"login with a valid cookie: nobody else is pushed out");
|
||||||
|
fake_now = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scenario_login_without_cookie_replaces_least_recently_used(void)
|
||||||
|
{
|
||||||
|
static const char post[] =
|
||||||
|
"POST /login HTTP/1.1\r\n"
|
||||||
|
"Content-Length: 8\r\n"
|
||||||
|
"Content-Type: application/x-www-form-urlencoded\r\n"
|
||||||
|
"\r\n"
|
||||||
|
"pwd=1234";
|
||||||
|
|
||||||
|
login_session_start();
|
||||||
|
fill_sessions();
|
||||||
|
client_send(TCP_ACK | TCP_PSH, post, (int)strlen(post));
|
||||||
|
CHECK(stream_contains("Location: index.html\r\n"),
|
||||||
|
"login without a cookie: accepted");
|
||||||
|
CHECK(strcmp(slot_id(1), "aaaaaaaaaaaa") != 0,
|
||||||
|
"login without a cookie: the least recently used slot is taken");
|
||||||
|
CHECK(others_kept(0, 2, 3),
|
||||||
|
"login without a cookie: the other three stay");
|
||||||
|
fake_now = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void scenario_fragmented_get_without_cookie(void)
|
static void scenario_fragmented_get_without_cookie(void)
|
||||||
{
|
{
|
||||||
static const char first[] =
|
static const char first[] =
|
||||||
@@ -1041,7 +1115,7 @@ static void scenario_upload(const char *name, const char *part_type, int split)
|
|||||||
session_start(MSS_FULL);
|
session_start(MSS_FULL);
|
||||||
strcpy(session_id, "0123456789ab");
|
strcpy(session_id, "0123456789ab");
|
||||||
session_timeout = 200;
|
session_timeout = 200;
|
||||||
last_session_use = 0; /* read_reg_timer() returns zero in this bench. */
|
last_session_use[0] = 0; /* read_reg_timer() returns zero in this bench. */
|
||||||
flash_size = 0x100000;
|
flash_size = 0x100000;
|
||||||
flash_written_len = 0;
|
flash_written_len = 0;
|
||||||
flash_write_bad = 0;
|
flash_write_bad = 0;
|
||||||
@@ -1082,6 +1156,115 @@ static void scenario_upload(const char *name, const char *part_type, int split)
|
|||||||
flash_size = saved_flash_size;
|
flash_size = saved_flash_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern uint32_t uptr;
|
||||||
|
|
||||||
|
#define UPLOAD_LEN 600
|
||||||
|
#define UPLOAD_BOUNDARY "\r\n--XyZ"
|
||||||
|
#define UPLOAD_TRAILER UPLOAD_BOUNDARY "--\r\n"
|
||||||
|
|
||||||
|
static int upload_in_two(uint8_t *body, uint16_t body_len, uint16_t split)
|
||||||
|
{
|
||||||
|
uptr = FIRMWARE_UPLOAD_START;
|
||||||
|
write_len = 0;
|
||||||
|
bindex = 0;
|
||||||
|
verify_crc = 0;
|
||||||
|
flash_written_len = 0;
|
||||||
|
flash_write_bad = 0;
|
||||||
|
strcpy((char *)boundary, UPLOAD_BOUNDARY);
|
||||||
|
uip_conn = &uip_conns[0];
|
||||||
|
uip_conn->appstate.tstate = TSTATE_POST;
|
||||||
|
|
||||||
|
upload_settings.p = body;
|
||||||
|
upload_settings.bptr = 0;
|
||||||
|
upload_settings.plen = split;
|
||||||
|
stream_upload();
|
||||||
|
if (uip_conn->appstate.tstate == TSTATE_POST) {
|
||||||
|
upload_settings.p = body + split;
|
||||||
|
upload_settings.bptr = 0;
|
||||||
|
upload_settings.plen = body_len - split;
|
||||||
|
stream_upload();
|
||||||
|
}
|
||||||
|
return uip_conn->appstate.tstate == TSTATE_NONE
|
||||||
|
&& uptr == FIRMWARE_UPLOAD_START + UPLOAD_LEN && !flash_write_bad
|
||||||
|
&& flash_written_len == UPLOAD_LEN + 1 && !flash_written[UPLOAD_LEN];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scenario_upload_cr_before_boundary(void)
|
||||||
|
{
|
||||||
|
uint8_t body[UPLOAD_LEN + sizeof(UPLOAD_TRAILER)];
|
||||||
|
uint16_t body_len, split;
|
||||||
|
int completed = 0, intact = 0, splits = 0;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < UPLOAD_LEN; i++)
|
||||||
|
body[i] = pattern(i);
|
||||||
|
body[UPLOAD_LEN - 2] = 'x';
|
||||||
|
body[UPLOAD_LEN - 1] = '\r';
|
||||||
|
body_len = UPLOAD_LEN + sizeof(UPLOAD_TRAILER) - 1;
|
||||||
|
memcpy(body + UPLOAD_LEN, UPLOAD_TRAILER, sizeof(UPLOAD_TRAILER) - 1);
|
||||||
|
|
||||||
|
for (split = 0; split <= body_len; split++) {
|
||||||
|
splits++;
|
||||||
|
if (upload_in_two(body, body_len, split)) {
|
||||||
|
completed++;
|
||||||
|
if (!memcmp(flash_written, body, UPLOAD_LEN))
|
||||||
|
intact++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (verbose)
|
||||||
|
printf(" %d of %d splits complete, %d intact\n", completed, splits, intact);
|
||||||
|
|
||||||
|
CHECK(completed == splits,
|
||||||
|
"upload: an image ending in CR still finds the closing boundary");
|
||||||
|
CHECK(intact == splits,
|
||||||
|
"upload: the CR and the bytes before it reach the flash unchanged");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int upload_whole_and_split(uint8_t *body, uint16_t body_len)
|
||||||
|
{
|
||||||
|
return upload_in_two(body, body_len, body_len) && !memcmp(flash_written, body, UPLOAD_LEN)
|
||||||
|
&& upload_in_two(body, body_len, UPLOAD_LEN) && !memcmp(flash_written, body, UPLOAD_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scenario_upload_last_byte(void)
|
||||||
|
{
|
||||||
|
uint8_t body[UPLOAD_LEN + sizeof(UPLOAD_TRAILER)];
|
||||||
|
uint16_t body_len = UPLOAD_LEN + sizeof(UPLOAD_TRAILER) - 1;
|
||||||
|
int bad = -1;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < UPLOAD_LEN; i++)
|
||||||
|
body[i] = pattern(i);
|
||||||
|
memcpy(body + UPLOAD_LEN, UPLOAD_TRAILER, sizeof(UPLOAD_TRAILER) - 1);
|
||||||
|
for (int last = 0; last < 256 && bad < 0; last++) {
|
||||||
|
body[UPLOAD_LEN - 1] = last;
|
||||||
|
if (!upload_whole_and_split(body, body_len))
|
||||||
|
bad = last;
|
||||||
|
}
|
||||||
|
if (bad >= 0)
|
||||||
|
printf(" last byte 0x%02x loses the closing boundary\n", bad);
|
||||||
|
CHECK(bad < 0, "upload: the part ends after the payload whatever its last byte");
|
||||||
|
|
||||||
|
body[UPLOAD_LEN - 1] = '\r';
|
||||||
|
body[UPLOAD_LEN - 2] = '\r';
|
||||||
|
CHECK(upload_whole_and_split(body, body_len), "upload: an even run of CR before the boundary");
|
||||||
|
body[UPLOAD_LEN - 3] = '\r';
|
||||||
|
CHECK(upload_whole_and_split(body, body_len), "upload: an odd run of CR before the boundary");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scenario_upload_broken_matches(void)
|
||||||
|
{
|
||||||
|
uint8_t body[UPLOAD_LEN + sizeof(UPLOAD_TRAILER)];
|
||||||
|
uint16_t body_len = UPLOAD_LEN + sizeof(UPLOAD_TRAILER) - 1;
|
||||||
|
|
||||||
|
memcpy(body + UPLOAD_LEN, UPLOAD_TRAILER, sizeof(UPLOAD_TRAILER) - 1);
|
||||||
|
memset(body, '\r', UPLOAD_LEN);
|
||||||
|
CHECK(upload_whole_and_split(body, body_len),
|
||||||
|
"upload: a run of CR longer than a flash page is staged intact");
|
||||||
|
for (uint16_t i = 0; i < UPLOAD_LEN; i++)
|
||||||
|
body[i] = "\r\n-"[i % 3];
|
||||||
|
CHECK(upload_whole_and_split(body, body_len),
|
||||||
|
"upload: repeated partial delimiters are staged as payload");
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc > 1 && !strcmp(argv[1], "-v"))
|
if (argc > 1 && !strcmp(argv[1], "-v"))
|
||||||
@@ -1113,6 +1296,12 @@ int main(int argc, char **argv)
|
|||||||
scenario_upload("octet-stream control", "Content-Type: application/octet-stream\r\n", 0);
|
scenario_upload("octet-stream control", "Content-Type: application/octet-stream\r\n", 0);
|
||||||
scenario_upload("MacBinary, split part terminator", "Content-Type: application/macbinary\r\n", 1);
|
scenario_upload("MacBinary, split part terminator", "Content-Type: application/macbinary\r\n", 1);
|
||||||
scenario_upload("no part Content-Type", "", 0);
|
scenario_upload("no part Content-Type", "", 0);
|
||||||
|
scenario_upload_cr_before_boundary();
|
||||||
|
scenario_upload_last_byte();
|
||||||
|
scenario_upload_broken_matches();
|
||||||
|
|
||||||
|
scenario_login_with_valid_cookie_reuses_its_slot();
|
||||||
|
scenario_login_without_cookie_replaces_least_recently_used();
|
||||||
|
|
||||||
printf("\n%s (%d failure%s)\n",
|
printf("\n%s (%d failure%s)\n",
|
||||||
failures ? "BENCH: FAILURES" : "BENCH: ALL PASS",
|
failures ? "BENCH: FAILURES" : "BENCH: ALL PASS",
|
||||||
|
|||||||
@@ -98,6 +98,7 @@
|
|||||||
#include "../rtl837x_regs.h"
|
#include "../rtl837x_regs.h"
|
||||||
|
|
||||||
extern __xdata uint8_t rx_headers[16];
|
extern __xdata uint8_t rx_headers[16];
|
||||||
|
extern volatile __xdata uint32_t ticks;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Variable definitions. */
|
/* Variable definitions. */
|
||||||
@@ -243,6 +244,9 @@ __xdata struct uip_stats uip_stat;
|
|||||||
|
|
||||||
#if UIP_LOGGING == 1
|
#if UIP_LOGGING == 1
|
||||||
#define UIP_LOG(m) print_string_newline_no_syslog(m);
|
#define UIP_LOG(m) print_string_newline_no_syslog(m);
|
||||||
|
#define FRAGDROP_WINDOW (5 * SYS_TICK_HZ)
|
||||||
|
static __xdata u16_t fragdrop_mark;
|
||||||
|
static __xdata u8_t fragdrop_count;
|
||||||
#else
|
#else
|
||||||
#define UIP_LOG(m)
|
#define UIP_LOG(m)
|
||||||
#endif /* UIP_LOGGING == 1 */
|
#endif /* UIP_LOGGING == 1 */
|
||||||
@@ -710,6 +714,17 @@ uip_process(u8_t flag) __banked
|
|||||||
/* Check if we were invoked because of the perodic timer fireing. */
|
/* Check if we were invoked because of the perodic timer fireing. */
|
||||||
} else if(flag == UIP_TIMER) {
|
} else if(flag == UIP_TIMER) {
|
||||||
// print_string("T1\n");
|
// print_string("T1\n");
|
||||||
|
#if UIP_LOGGING == 1
|
||||||
|
if(fragdrop_count && (u16_t)ticks - fragdrop_mark >= FRAGDROP_WINDOW) {
|
||||||
|
print_string_no_syslog("ip: fragments dropped: ");
|
||||||
|
itoa_no_syslog(fragdrop_count);
|
||||||
|
if(fragdrop_count == 0xff)
|
||||||
|
write_char_no_syslog('+');
|
||||||
|
write_char_no_syslog('\n');
|
||||||
|
fragdrop_mark = (u16_t)ticks;
|
||||||
|
fragdrop_count = 0;
|
||||||
|
}
|
||||||
|
#endif /* UIP_LOGGING == 1 */
|
||||||
#if UIP_IDLE_TIMEOUT
|
#if UIP_IDLE_TIMEOUT
|
||||||
if(uip_connr == uip_conns) {
|
if(uip_connr == uip_conns) {
|
||||||
uip_idle_age = 0;
|
uip_idle_age = 0;
|
||||||
@@ -915,7 +930,10 @@ uip_process(u8_t flag) __banked
|
|||||||
#else /* UIP_REASSEMBLY */
|
#else /* UIP_REASSEMBLY */
|
||||||
UIP_STAT(++uip_stat.ip.drop);
|
UIP_STAT(++uip_stat.ip.drop);
|
||||||
UIP_STAT(++uip_stat.ip.fragerr);
|
UIP_STAT(++uip_stat.ip.fragerr);
|
||||||
UIP_LOG("ip: fragment dropped.");
|
#if UIP_LOGGING == 1
|
||||||
|
if(fragdrop_count != 0xff)
|
||||||
|
++fragdrop_count;
|
||||||
|
#endif /* UIP_LOGGING == 1 */
|
||||||
goto drop;
|
goto drop;
|
||||||
#endif /* UIP_REASSEMBLY */
|
#endif /* UIP_REASSEMBLY */
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user