mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
Compare commits
36
Commits
4c8e0ce975
...
8a7b146892
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a7b146892 | ||
|
|
0998a9dfaa | ||
|
|
aded07730e | ||
|
|
58d059384d | ||
|
|
a7692022f1 | ||
|
|
e26693826e | ||
|
|
be6bd2a5b3 | ||
|
|
6c43091b7a | ||
|
|
b57b7d1a3d | ||
|
|
fc86ea8be5 | ||
|
|
91780110f2 | ||
|
|
f0e9953081 | ||
|
|
1c9bf10b87 | ||
|
|
2e2529be27 | ||
|
|
f6348765b4 | ||
|
|
6411c5157c | ||
|
|
d06dc3e5f8 | ||
|
|
dd7f9f7c7b | ||
|
|
3b8dba6e87 | ||
|
|
a259587bf9 | ||
|
|
f23d840cee | ||
|
|
f46ef3a43c | ||
|
|
81af3a29a2 | ||
|
|
5a55524115 | ||
|
|
6b39bcc448 | ||
|
|
40ce742d04 | ||
|
|
373a21f4a1 | ||
|
|
73d9a8ccb1 | ||
|
|
e50d3c6950 | ||
|
|
4db1ccbbd9 | ||
|
|
ccafa01c74 | ||
|
|
cb43b3cbd6 | ||
|
|
9d4e531306 | ||
|
|
f00dbab0c4 | ||
|
|
bc46646398 | ||
|
|
5fa6c36b73 |
No files matched your search
@@ -0,0 +1,25 @@
|
|||||||
|
# Change Log
|
||||||
|
|
||||||
|
## [0.x] - 2026-xx-XX
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
## Breaking changes
|
||||||
|
|
||||||
|
- Config
|
||||||
|
- VLAN don't accept port `u`-suffix anymore.
|
||||||
|
So `vlan 1 4u` is not valid anymore.
|
||||||
|
Replace it with `vlan 1 4`.
|
||||||
|
- Commands
|
||||||
|
- port zero/`0` is treated as the `CPU_PORT`. #326
|
||||||
|
- Many commands don't accept the CPU_PORT anymore. See #334.
|
||||||
|
When the CPU_PORT is needed, the command/service will add the CPU_PORT automaticly.
|
||||||
|
Only `isolate` accept the CPU_PORT as destination port.
|
||||||
|
|
||||||
|
## [v0.1_aplha] - 2025-11-03
|
||||||
|
|
||||||
|
First release.
|
||||||
+34
-3
@@ -48,6 +48,7 @@ __xdata uint16_t vlan_ptr;
|
|||||||
__xdata char port_names[9][PORT_NAME_SIZE];
|
__xdata char port_names[9][PORT_NAME_SIZE];
|
||||||
|
|
||||||
extern __xdata uint16_t management_vlan;
|
extern __xdata uint16_t management_vlan;
|
||||||
|
extern __xdata struct uip_eth_addr uip_ethaddr;
|
||||||
extern __xdata uint8_t sfp_speed[2];
|
extern __xdata uint8_t sfp_speed[2];
|
||||||
extern __xdata uint8_t sfp_pins_last;
|
extern __xdata uint8_t sfp_pins_last;
|
||||||
extern __xdata uint8_t sfp_options[2];
|
extern __xdata uint8_t sfp_options[2];
|
||||||
@@ -66,6 +67,10 @@ __xdata char save_cmd;
|
|||||||
|
|
||||||
__xdata uint8_t ip[4];
|
__xdata uint8_t ip[4];
|
||||||
|
|
||||||
|
/* Scratch for parse_syslog(), in xdata: a local here would take internal RAM
|
||||||
|
* the linker has none of. */
|
||||||
|
__xdata uint8_t syslog_port_was_on;
|
||||||
|
|
||||||
// These variables combined create a Fixed-capacity vector/bounded buffer.
|
// These variables combined create a Fixed-capacity vector/bounded buffer.
|
||||||
// `N_WORDS`: The total number of command arguments that can be tracked.
|
// `N_WORDS`: The total number of command arguments that can be tracked.
|
||||||
// `cmd_words_len` stores the number of arguments found inside `cmd_buffer`
|
// `cmd_words_len` stores the number of arguments found inside `cmd_buffer`
|
||||||
@@ -476,7 +481,9 @@ void parse_vlan(void)
|
|||||||
vlan_settings.vlan = atoi_results_short;
|
vlan_settings.vlan = atoi_results_short;
|
||||||
|
|
||||||
if (cmd_compare(2, "mgmt")) {
|
if (cmd_compare(2, "mgmt")) {
|
||||||
|
port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, true);
|
||||||
management_vlan = vlan_settings.vlan;
|
management_vlan = vlan_settings.vlan;
|
||||||
|
port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, false);
|
||||||
if (!vlan_settings.vlan)
|
if (!vlan_settings.vlan)
|
||||||
print_string("Management VLAN disabled\n");
|
print_string("Management VLAN disabled\n");
|
||||||
else
|
else
|
||||||
@@ -542,7 +549,7 @@ void parse_vlan(void)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
err:
|
err:
|
||||||
print_string("Error: vlan (<vlan-id>|show) [port][t/u]...\n");
|
print_string("Error: vlan (<vlan-id>|show) [port][t]...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1412,6 +1419,7 @@ void parse_syslog(void)
|
|||||||
if (syslog_state.enabled) {
|
if (syslog_state.enabled) {
|
||||||
print_string("enabled, sending to ");
|
print_string("enabled, sending to ");
|
||||||
print_ip(syslog_state.server_ip);
|
print_ip(syslog_state.server_ip);
|
||||||
|
write_char(':'); itoa_short(syslog_state.server_port);
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
} else {
|
} else {
|
||||||
print_string("disabled\n");
|
print_string("disabled\n");
|
||||||
@@ -1440,11 +1448,34 @@ void parse_syslog(void)
|
|||||||
} else {
|
} else {
|
||||||
print_string("Invalid IP address\n");
|
print_string("Invalid IP address\n");
|
||||||
}
|
}
|
||||||
|
} else if (cmd_compare(1, "port")) {
|
||||||
|
if (cmd_words_len < 3) { // no additional argument -> print current port
|
||||||
|
print_string("Current syslog port: ");
|
||||||
|
itoa_short(syslog_state.server_port); write_char('\n');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* atoi_short() returns zero for no digits and for a value past
|
||||||
|
* 65535; port zero is not a port either, so both tests are needed. */
|
||||||
|
if (!atoi_short(cmd_words_b[2]) || !atoi_results_short) {
|
||||||
|
print_string("Invalid port\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* The port is frozen into the connection by uip_udp_new(), so
|
||||||
|
* changing it has to tear the connection down and build a new one -
|
||||||
|
* same dance as setting the address above. */
|
||||||
|
syslog_port_was_on = syslog_state.enabled;
|
||||||
|
if (syslog_port_was_on)
|
||||||
|
syslog_stop();
|
||||||
|
print_string("Setting new syslog port.\n");
|
||||||
|
syslog_state.server_port = atoi_results_short;
|
||||||
|
if (syslog_port_was_on)
|
||||||
|
syslog_start();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
print_string("Error: syslog [on|off|ip [ip-address]]\n");
|
print_string("Error: syslog [on|off|ip [ip-address]|port [number]]\n");
|
||||||
print_string(" on/off enables or disables syslog, ip sets the syslog server IP address\n");
|
print_string(" on/off enables or disables syslog, ip sets the syslog server IP address,\n");
|
||||||
|
print_string(" port sets the destination UDP port (default 514)\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ void cmd_tokenize(void) __banked;
|
|||||||
void cmd_parser(void) __banked;
|
void cmd_parser(void) __banked;
|
||||||
void execute_config(void) __banked;
|
void execute_config(void) __banked;
|
||||||
void execute_commands(__xdata uint8_t *p) __banked;
|
void execute_commands(__xdata uint8_t *p) __banked;
|
||||||
|
void print_ip(__xdata uint8_t *ptr);
|
||||||
void print_sw_version(void) __banked;
|
void print_sw_version(void) __banked;
|
||||||
void clear_command_history(void) __banked;
|
void clear_command_history(void) __banked;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
Hisource Hi-K0402WS V2
|
||||||
|
|
||||||
|
RTL8372-based 4×2.5G + 2×SFP+ unmanaged switch.
|
||||||
|
|
||||||
|
Using SPI clamp in-board is the only method for initial installation.
|
||||||
|
|
||||||
|
### Label specifications
|
||||||
|
|
||||||
|
- **Manufacturer**: HISOURCE
|
||||||
|
- **Model**: Hi-K0402WS V2
|
||||||
|
- **Ports**:
|
||||||
|
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||||
|
- 2 × SFP+: 1G / 2.5G / 10G
|
||||||
|
|
||||||
|
### What works
|
||||||
|
|
||||||
|
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||||
|
- Both SFP+ ports supporting 1G, 2.5G and 10G modules
|
||||||
|
- LEDs: amber (2.5G) and green (1G/100M/10M) per copper port; combined link/act on SFP ports
|
||||||
|
|
||||||
|
### PCB overview
|
||||||
|
|
||||||
|
**Board markings**
|
||||||
|
- PCB-K0402WS-V2.0
|
||||||
|
- DIP-K0402WS-V2.0
|
||||||
|
|
||||||
|
**Key components**
|
||||||
|
- U1: SPI NOR flash, 2 MiB
|
||||||
|
- S1: unpopulated slide switch footprint (three through-holes used as serial console)
|
||||||
|
|
||||||
|
Front panel
|
||||||
|
|
||||||
|
<img src="photos/PCB-K0402WS-V2.0/chassis-front.jpg" width="400" />
|
||||||
|
|
||||||
|
Bottom label
|
||||||
|
|
||||||
|
<img src="photos/PCB-K0402WS-V2.0/chassis-bottom.jpg" width="400" />
|
||||||
|
|
||||||
|
Top side (PCB)
|
||||||
|
|
||||||
|
<img src="photos/PCB-K0402WS-V2.0/PCB-top.jpg" width="300" />
|
||||||
|
|
||||||
|
### Port layout
|
||||||
|
|
||||||
|
| Front panel position | Logical port | Physical port | Type |
|
||||||
|
|----------------------|--------------|---------------|---------|
|
||||||
|
| SFP left | 8 | 5 | SFP+ |
|
||||||
|
| RJ45 1 | 4 | 1 | Copper |
|
||||||
|
| RJ45 2 | 5 | 2 | Copper |
|
||||||
|
| RJ45 3 | 6 | 3 | Copper |
|
||||||
|
| RJ45 4 | 7 | 4 | Copper |
|
||||||
|
| SFP right | 3 | 6 | SFP+ |
|
||||||
|
|
||||||
|
### Serial console
|
||||||
|
|
||||||
|
The PCB has three unpopulated through-holes intended for a slide switch, directly connected to UART0.
|
||||||
|
Numbered from the left (SFP port side), the pinout is:
|
||||||
|
|
||||||
|
| Position (left→right) | Signal | GPIO |
|
||||||
|
|-----------------------|--------|--------------------------|
|
||||||
|
| 1 (leftmost) | RX | GPIO32\_UART0\_RX (32) |
|
||||||
|
| 2 (middle) | GND | GND |
|
||||||
|
| 3 (rightmost) | TX | GPIO31\_UART0\_TX (31) |
|
||||||
|
|
||||||
|
- **Settings**: 115200 baud / 8N1 / 3.3V TTL
|
||||||
|
- Connect a USB-TTL adapter: adapter TX → pin 1, GND → pin 2, adapter RX → pin 3
|
||||||
|
|
||||||
|
### LED configuration
|
||||||
|
|
||||||
|
Copper ports use LED SET0, SFP ports use LED SET1.
|
||||||
|
|
||||||
|
| SET | LED0 | LED2 |
|
||||||
|
|------|--------------------------------------------------|---------------------------------------------------|
|
||||||
|
| SET0 | Amber — lights on 2.5G link | Green — lights on 1G / 100M / 10M link |
|
||||||
|
| SET1 | All speeds — lights on any link with activity | — |
|
||||||
|
|
||||||
|
LED pad to physical port mapping:
|
||||||
|
|
||||||
|
| GPIO pads | Port |
|
||||||
|
|-----------|-------------------------|
|
||||||
|
| GPIO8–11 | Physical port 5 (left SFP) |
|
||||||
|
| GPIO12–14 | Physical port 1 (RJ45 1) |
|
||||||
|
| GPIO15–17 | Physical port 2 (RJ45 2) |
|
||||||
|
| GPIO18–20 | Physical port 3 (RJ45 3) |
|
||||||
|
| GPIO21–23 | Physical port 4 (RJ45 4) |
|
||||||
|
| GPIO24–27 | Physical port 6 (right SFP) |
|
||||||
|
|
||||||
|
### SFP GPIO assignments
|
||||||
|
|
||||||
|
| SFP | pin\_detect (ModAbs) | pin\_los | SerDes | I2C SDA | I2C SCL |
|
||||||
|
|------------------|-----------------------------|------------------------|--------|----------------------|--------------------------|
|
||||||
|
| Left (logical 8) | GPIO30\_ACL\_BIT3\_EN | GPIO37 | SDS1 | GPIO39\_I2C\_SDA4 | GPIO40\_I2C\_SCL3\_MDC1 |
|
||||||
|
| Right (logical 3)| GPIO50\_I2C\_SCL2\_UART1\_TX | GPIO51\_I2C\_SDA2\_UART1\_RX | SDS0 | GPIO41\_I2C\_SDA3\_MDIO1 | GPIO40\_I2C\_SCL3\_MDC1 |
|
||||||
|
|
||||||
|
GPIO assignments were verified by observing GPIO state changes during SFP module insertion/removal
|
||||||
|
and cross-checked against an original firmware register dump.
|
||||||
|
`pin_tx_disable` is GPIO\_NA on both ports (original firmware keeps all GPIOs as inputs).
|
||||||
@@ -19,6 +19,9 @@ of the device just above the big label, might be covered by a QC sticker.
|
|||||||
|
|
||||||
<img src="photos/PCB-K0402WS-V3.0/Ztyuav_Z-QWYT0402_label.jpg" width="300" />
|
<img src="photos/PCB-K0402WS-V3.0/Ztyuav_Z-QWYT0402_label.jpg" width="300" />
|
||||||
|
|
||||||
|
* Siscolink SL-G0402F
|
||||||
|
|
||||||
|
<img src="photos/PCB-K0402WS-V3.0/Siscolink SL-G0402F.jpg" width="300"/>
|
||||||
### Programming
|
### Programming
|
||||||
|
|
||||||
Using SPI clamp in-board is the only method for initial installation.
|
Using SPI clamp in-board is the only method for initial installation.
|
||||||
|
|||||||
+36
-17
@@ -1,9 +1,11 @@
|
|||||||
### ZX-SWTGW215AS
|
# ZX-SWTGW215AS
|
||||||
|
|
||||||
## Brands
|
## Brands
|
||||||
|
|
||||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| Lianguo | ZX-SWTGW215AS | Yes | PCB-SWTG115AS-V2.0 | FM25Q16A | 8272 |
|
| Lianguo | ZX-SWTGW215AS | Yes | PCB-SWTG115AS-V2.0 | FM25Q16A | 8372 |
|
||||||
|
| sold as Lianguo, actual device unbranded | ZX-SWTGW215AS | Yes | PCB-SWTG115AS-V2.1 | W25Q16JVSIQ (2MiB) | 8372 |
|
||||||
|
|
||||||
## RTLPlayground target
|
## RTLPlayground target
|
||||||
|
|
||||||
@@ -12,13 +14,23 @@ Use machine target `MACHINE_LIANGUO_ZX_SWTGW215AS` for this device.
|
|||||||
Physical hardware verification: 5x RJ45 ports + 1x SFP port.
|
Physical hardware verification: 5x RJ45 ports + 1x SFP port.
|
||||||
Port 5 RJ45 is interfaced through a RTL8221B IC.
|
Port 5 RJ45 is interfaced through a RTL8221B IC.
|
||||||
|
|
||||||
## PCB
|
## Label (V2.0)
|
||||||
|
|
||||||
<img src="photos/ZX-SWTGW215AS/pcb_top.jpg" width="300" />
|
<img src="photos/ZX-SWTGW215AS-V2.0/label.jpg" width="300" />
|
||||||
|
|
||||||
# Connectors
|
## PCB (V2.0)
|
||||||
|
|
||||||
## Port overview
|
<img src="photos/ZX-SWTGW215AS-V2.0/pcb_top.jpg" width="300" />
|
||||||
|
<img src="photos/ZX-SWTGW215AS-V2.0/pcb_bottom.jpg" width="300" />
|
||||||
|
|
||||||
|
## PCB (V2.1)
|
||||||
|
|
||||||
|
<img src="photos/ZX-SWTGW215AS-V2.1/pcb-top.jpg" width="300" />
|
||||||
|
<img src="photos/ZX-SWTGW215AS-V2.1/pcb-bottom.jpg" width="300" />
|
||||||
|
|
||||||
|
## Connectors
|
||||||
|
|
||||||
|
### Port overview
|
||||||
|
|
||||||
```
|
```
|
||||||
┌──────────────────────────────────────────────────────────────────────────────────┐
|
┌──────────────────────────────────────────────────────────────────────────────────┐
|
||||||
@@ -36,7 +48,7 @@ Port 5 RJ45 is interfaced through a RTL8221B IC.
|
|||||||
| RJ45 | 3, 4, 5, 6, 7 | 1-5 |
|
| RJ45 | 3, 4, 5, 6, 7 | 1-5 |
|
||||||
| SFP | 8 | 6 |
|
| SFP | 8 | 6 |
|
||||||
|
|
||||||
## J4
|
### J4
|
||||||
|
|
||||||
* Location: SFP connector `J4`.
|
* Location: SFP connector `J4`.
|
||||||
* Connected to: 10GMAC number 8, SerDes 1.
|
* Connected to: 10GMAC number 8, SerDes 1.
|
||||||
@@ -48,10 +60,11 @@ Port 5 RJ45 is interfaced through a RTL8221B IC.
|
|||||||
|5| MODDEF1 – SCL | GPIO40 | I2C SCL |
|
|5| MODDEF1 – SCL | GPIO40 | I2C SCL |
|
||||||
|6| MODDEF0 – PRESENT | GPIO30 | Detect |
|
|6| MODDEF0 – PRESENT | GPIO30 | Detect |
|
||||||
|8| LOS | GPIO37 | RX Loss of Signal |
|
|8| LOS | GPIO37 | RX Loss of Signal |
|
||||||
### Notes
|
|
||||||
|
#### Notes
|
||||||
* Not all signals were mapped mechanically, hence they've been left out of documentation.
|
* Not all signals were mapped mechanically, hence they've been left out of documentation.
|
||||||
|
|
||||||
## T3, Slave Interface
|
### T3, Slave Interface
|
||||||
|
|
||||||
This connector goes to U4 `I2C EEPROM` and U10 `SPI FLASH` (mappings identical to SWTG024AS).
|
This connector goes to U4 `I2C EEPROM` and U10 `SPI FLASH` (mappings identical to SWTG024AS).
|
||||||
|
|
||||||
@@ -65,11 +78,12 @@ For detailed Slave Interface functionality and protocol information, see [T3 doc
|
|||||||
|4| VCC |
|
|4| VCC |
|
||||||
|5| 33R -> U10-P2 | SPI-DO/D1 |
|
|5| 33R -> U10-P2 | SPI-DO/D1 |
|
||||||
|6| U10-P1 | SPI-CS |
|
|6| U10-P1 | SPI-CS |
|
||||||
### Notes
|
|
||||||
|
#### Notes
|
||||||
* 1 pin is square shaped.
|
* 1 pin is square shaped.
|
||||||
|
|
||||||
|
|
||||||
## T5, Serial Console
|
### T5, Serial Console
|
||||||
|
|
||||||
|`T5` pin|GPIO|Signal|
|
|`T5` pin|GPIO|Signal|
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
@@ -77,10 +91,11 @@ For detailed Slave Interface functionality and protocol information, see [T3 doc
|
|||||||
| 2 | GND | |
|
| 2 | GND | |
|
||||||
| 3 | GPIO32 | U0RXD (Input) |
|
| 3 | GPIO32 | U0RXD (Input) |
|
||||||
| 4 | 3V3 | |
|
| 4 | 3V3 | |
|
||||||
### Notes
|
|
||||||
|
#### Notes
|
||||||
* 1 pin is square shaped.
|
* 1 pin is square shaped.
|
||||||
|
|
||||||
## T8
|
### T8
|
||||||
|
|
||||||
|`T8` pin|GPIO|Signal|
|
|`T8` pin|GPIO|Signal|
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
@@ -91,18 +106,19 @@ For detailed Slave Interface functionality and protocol information, see [T3 doc
|
|||||||
| 5 | GPIO47 | |
|
| 5 | GPIO47 | |
|
||||||
| 6 | GPIO49 | |
|
| 6 | GPIO49 | |
|
||||||
|
|
||||||
### Notes
|
#### Notes
|
||||||
* 1 pin is square shaped.
|
* 1 pin is square shaped.
|
||||||
* Mapping unverified but assumed the same as [LIANGUO SWTG024AS](SWTG024AS.md#t8).
|
* Mapping unverified but assumed the same as [LIANGUO SWTG024AS](SWTG024AS.md#t8).
|
||||||
|
|
||||||
# Reset Circuit
|
## Reset Circuit
|
||||||
| Function | GPIO |
|
| Function | GPIO |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Reset button | GPIO54 |
|
| Reset button | GPIO54 |
|
||||||
|
|
||||||
### Notes
|
### Notes
|
||||||
* Circuit is active-low
|
* Circuit is active-low
|
||||||
|
|
||||||
# GPIO
|
## GPIO
|
||||||
|
|
||||||
Note: T3/U4/U10-related signal annotations below are copied from [LIANGUO SWTG024AS T3 section](SWTG024AS.md#t3-slave-interface) as well as T8 port from [LIANGUO SWTG024AS T8 section](SWTG024AS.md#t8). They should be treated as assumed identical for ZX-SWTGW215AS as it has not been 100% confirmed true at the moment.
|
Note: T3/U4/U10-related signal annotations below are copied from [LIANGUO SWTG024AS T3 section](SWTG024AS.md#t3-slave-interface) as well as T8 port from [LIANGUO SWTG024AS T8 section](SWTG024AS.md#t8). They should be treated as assumed identical for ZX-SWTGW215AS as it has not been 100% confirmed true at the moment.
|
||||||
|
|
||||||
@@ -141,7 +157,7 @@ Note: T3/U4/U10-related signal annotations below are copied from [LIANGUO SWTG02
|
|||||||
| 40000000 | GPIO30 | J4-6 | SFP DETECT | | GPIO62 | | |
|
| 40000000 | GPIO30 | J4-6 | SFP DETECT | | GPIO62 | | |
|
||||||
| 80000000 | GPIO31 | T5-1 | U0TXD | | GPIO63 | | |
|
| 80000000 | GPIO31 | T5-1 | U0TXD | | GPIO63 | | |
|
||||||
|
|
||||||
# LEDs
|
## LEDs
|
||||||
|
|
||||||
| NAME | GPIO | Port(s) | Function | Notes |
|
| NAME | GPIO | Port(s) | Function | Notes |
|
||||||
| ---- | ---- | ---- | ---- | ---- |
|
| ---- | ---- | ---- | ---- | ---- |
|
||||||
@@ -162,3 +178,6 @@ Note: T3/U4/U10-related signal annotations below are copied from [LIANGUO SWTG02
|
|||||||
|
|
||||||
While [SWTG024AS.md](SWTG024AS.md) can be used as a general reference for hardware concepts and interface specifications, this device should not be assumed to be identical beside the difference implicitely highlighted below. Not all information has been validated for compatibility with the SWTG215AS. Consult the SWTG024AS documentation with caution and verify any critical details against this device's.
|
While [SWTG024AS.md](SWTG024AS.md) can be used as a general reference for hardware concepts and interface specifications, this device should not be assumed to be identical beside the difference implicitely highlighted below. Not all information has been validated for compatibility with the SWTG215AS. Consult the SWTG024AS documentation with caution and verify any critical details against this device's.
|
||||||
|
|
||||||
|
## Flashing
|
||||||
|
|
||||||
|
For devices with Winbond 25Q16JVSIQ, flashing is possible for example using flashprog with device "W25Q16.V". Note that you should not overwrite the whole flash to keep device-specific data (like the MAC address at 0x1fc000). Also, creating a backup of the entire falsh before is of course a very good idea.
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 170 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 115 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 84 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.5 MiB |
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.
|
After Width: | Height: | Size: 476 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 657 KiB |
@@ -7,6 +7,7 @@ The following devices have been tested and are fully working:
|
|||||||
| Davuaz | Da-K6501W | No | [PCB-K0501W-V2.0](devices/K0501W_V2_0.md) | | 5 + 1 |
|
| Davuaz | Da-K6501W | No | [PCB-K0501W-V2.0](devices/K0501W_V2_0.md) | | 5 + 1 |
|
||||||
| FOXNEO | FNS-1200P | No | [PCB-K0402W-U13-V2.0](devices/FNS-1200P.md) | 2M | 4 + 2 |
|
| FOXNEO | FNS-1200P | No | [PCB-K0402W-U13-V2.0](devices/FNS-1200P.md) | 2M | 4 + 2 |
|
||||||
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
||||||
|
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V2.0](devices/PCB-K0402WS-V2.0.md) | 2M | 4 + 2 |
|
||||||
| Hisource | Hi-K0801WS | No | [PCB-KO801W-V2.0](devices/HI-K0801WS.md) | | 8 + 1 |
|
| Hisource | Hi-K0801WS | No | [PCB-KO801W-V2.0](devices/HI-K0801WS.md) | | 8 + 1 |
|
||||||
| hongyavision | LG-SG5T1 | No | [PCB-SWTG024AS-V2.0_16895](devices/SWTG024AS-V2.0.md) | 0.5M | 5 + 1 |
|
| hongyavision | LG-SG5T1 | No | [PCB-SWTG024AS-V2.0_16895](devices/SWTG024AS-V2.0.md) | 0.5M | 5 + 1 |
|
||||||
| Horaco | HC-SWTGW215AS | Yes | [SWTG024AS-A-V2.0.1_19650 5C 1SFP](devices/SWTG024AS-A-V2.0.1_5C_1SFP.md) | ? | 5 + 1 |
|
| Horaco | HC-SWTGW215AS | Yes | [SWTG024AS-A-V2.0.1_19650 5C 1SFP](devices/SWTG024AS-A-V2.0.1_5C_1SFP.md) | ? | 5 + 1 |
|
||||||
@@ -19,11 +20,12 @@ 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 |
|
||||||
| 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](devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
| Lianguo | ZX-SWTGW215AS | Yes | [PCB-SWTG115AS-V2.0 / PCB-SWTG115AS-V2.1](devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
||||||
| Mokerlink| 2G040210GSM | Yes | [2M-PCB43-V1.1](devices/2M-PCB43-V1.1.md) | | 4 + 2 |
|
| Mokerlink| 2G040210GSM | Yes | [2M-PCB43-V1.1](devices/2M-PCB43-V1.1.md) | | 4 + 2 |
|
||||||
| Mokerlink| ZX-SWTGW218AS | Yes | [SWTG118AS-V2.0-16029](devices/SWTGW218AS.md) | 2M | 8 + 1 |
|
| Mokerlink| ZX-SWTGW218AS | Yes | [SWTG118AS-V2.0-16029](devices/SWTGW218AS.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 |
|
||||||
|
| SiscoLink | SL-G0402F | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
||||||
| Sodola | SL-SWTG124AS-D | Yes | [SWTG024AS-v2.0-17452](devices/SWTG024AS.md) | 2M | 4 + 2 |
|
| Sodola | SL-SWTG124AS-D | Yes | [SWTG024AS-v2.0-17452](devices/SWTG024AS.md) | 2M | 4 + 2 |
|
||||||
| Steamemo | IG204-V1 | No | [PB-2131](devices/STEAMEMO_IG204_V1.md) | | 4 + 2 |
|
| Steamemo | IG204-V1 | No | [PB-2131](devices/STEAMEMO_IG204_V1.md) | | 4 + 2 |
|
||||||
| TrendNet | TEG-S562 | No | [TEG-S563/EU H/W: V1.0R](devices/TEG-S562.md) | 2M | 4 + 2 |
|
| TrendNet | TEG-S562 | No | [TEG-S563/EU H/W: V1.0R](devices/TEG-S562.md) | 2M | 4 + 2 |
|
||||||
|
|||||||
+3
-3
@@ -69,9 +69,9 @@ void vlan_delete(uint16_t vlan) __banked;
|
|||||||
# VLAN configuration on the Serial Console
|
# VLAN configuration on the Serial Console
|
||||||
For testing the following commands are provided on the serial console:
|
For testing the following commands are provided on the serial console:
|
||||||
```
|
```
|
||||||
vlan <VLAN-ID> p[t/u]...
|
vlan <VLAN-ID> p[t]...
|
||||||
create or set vlan with given ID and the list of ports as members, a t
|
create or set vlan with given ID and the list of ports as members, a `t`
|
||||||
behind a port defines the port as a tagged member, the u is optional
|
behind a port defines the port as a tagged member.
|
||||||
|
|
||||||
vlan <VLAN-ID> d
|
vlan <VLAN-ID> d
|
||||||
deletes the VLAN
|
deletes the VLAN
|
||||||
|
|||||||
+19
-2
@@ -7,10 +7,11 @@ const conf_cmds = [
|
|||||||
/^netmask\s+(\d{1,3}\.){3}\d{1,3}$/,
|
/^netmask\s+(\d{1,3}\.){3}\d{1,3}$/,
|
||||||
/^syslog\s+(on|off)$/,
|
/^syslog\s+(on|off)$/,
|
||||||
/^syslog\s+ip\s+(\d{1,3}\.){3}\d{1,3}$/,
|
/^syslog\s+ip\s+(\d{1,3}\.){3}\d{1,3}$/,
|
||||||
|
/^syslog\s+port\s+\d{1,5}$/,
|
||||||
/^passwd\s+\S+$/,
|
/^passwd\s+\S+$/,
|
||||||
/^vlan\s+\d{1,4}\s+d$/,
|
/^vlan\s+\d{1,4}\s+d$/,
|
||||||
/^vlan\s+\d{1,4}\s+mgmt$/,
|
/^vlan\s+\d{1,4}\s+mgmt$/,
|
||||||
/^vlan\s+\d{1,4}(\s+[a-zA-Z]\w*)?(\s+\d{1,2}[tu]?)+$/,
|
/^vlan\s+\d{1,4}(\s+[a-zA-Z]\w*)?(\s+[1-9]t?)+$/,
|
||||||
/^pvid\s+\d{1,2}\s+\d{1,4}$/,
|
/^pvid\s+\d{1,2}\s+\d{1,4}$/,
|
||||||
/^ingress(\s+\d{1,2}[tua])+$/,
|
/^ingress(\s+\d{1,2}[tua])+$/,
|
||||||
/^ingress\s+[tua]$/,
|
/^ingress\s+[tua]$/,
|
||||||
@@ -36,12 +37,21 @@ const conf_cmds = [
|
|||||||
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
|
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
|
||||||
/^hostname\s+.{1,23}$/,
|
/^hostname\s+.{1,23}$/,
|
||||||
];
|
];
|
||||||
|
/* Commands that come in an on/off pair replace each other, which the list
|
||||||
|
* below cannot express: it drops lines starting with the text it matched, and
|
||||||
|
* "syslog off" does not start with "syslog on". Naming the stem separately
|
||||||
|
* keeps the pair collapsed without widening the match to the whole family. */
|
||||||
|
const conf_toggle = [
|
||||||
|
/^(syslog)\s+(?:on|off)$/,
|
||||||
|
];
|
||||||
|
|
||||||
const conf_overwrite = [
|
const conf_overwrite = [
|
||||||
/^ip\b/,
|
/^ip\b/,
|
||||||
/^gw\b/,
|
/^gw\b/,
|
||||||
/^netmask\b/,
|
/^netmask\b/,
|
||||||
/^syslog\s+ip\b/,
|
/^syslog\s+ip\b/,
|
||||||
/^syslog\b/,
|
/^syslog\s+port\b/,
|
||||||
|
/^syslog\s+(on|off)$/,
|
||||||
/^passwd\b/,
|
/^passwd\b/,
|
||||||
/^vlan\s+\d{1,4}\s+mgmt$/,
|
/^vlan\s+\d{1,4}\s+mgmt$/,
|
||||||
/^vlan\s+\d{1,4}(?!\s+mgmt\b)/,
|
/^vlan\s+\d{1,4}(?!\s+mgmt\b)/,
|
||||||
@@ -79,6 +89,13 @@ function parseConf(s){
|
|||||||
for (const x of conf_cmds)
|
for (const x of conf_cmds)
|
||||||
if (x.test(line)) { ignore = false; break; }
|
if (x.test(line)) { ignore = false; break; }
|
||||||
if (ignore) continue;
|
if (ignore) continue;
|
||||||
|
for (const x of conf_toggle) {
|
||||||
|
const t = line.match(x);
|
||||||
|
if (t) {
|
||||||
|
configuration = configuration.filter(item => item !== t[1] + " on" && item !== t[1] + " off");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (const x of conf_overwrite) {
|
for (const x of conf_overwrite) {
|
||||||
if (x.test(line)) {
|
if (x.test(line)) {
|
||||||
let m = line.match(x);
|
let m = line.match(x);
|
||||||
|
|||||||
+13
-4
@@ -52,8 +52,10 @@ function delL2(idx) {
|
|||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
xhttp.onreadystatechange = function() {
|
xhttp.onreadystatechange = function() {
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
var s = JSON.parse(xhttp.responseText);
|
if (JSON.parse(xhttp.responseText).result == 1) {
|
||||||
console.log("Entry deletion result: ", s.result);
|
l2All = l2All.filter(function(e) { return e.idx != idx; });
|
||||||
|
renderL2();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", "/l2_del.json?idx=" + idx, true);
|
xhttp.open("GET", "/l2_del.json?idx=" + idx, true);
|
||||||
@@ -116,6 +118,13 @@ function fillL2(s)
|
|||||||
renderL2();
|
renderL2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function delL2Button(e)
|
||||||
|
{
|
||||||
|
if (e.port == 'CPU')
|
||||||
|
return '';
|
||||||
|
return '<button type="button" onclick="delL2(' + e.idx + ');">' + t('l2_delete') + '</button>';
|
||||||
|
}
|
||||||
|
|
||||||
function paintL2(tbl, s)
|
function paintL2(tbl, s)
|
||||||
{
|
{
|
||||||
console.log("L2: ", JSON.stringify(s));
|
console.log("L2: ", JSON.stringify(s));
|
||||||
@@ -127,14 +136,14 @@ function paintL2(tbl, s)
|
|||||||
tbl.rows[i+1].cells[1].innerHTML = `${e.mac}`;
|
tbl.rows[i+1].cells[1].innerHTML = `${e.mac}`;
|
||||||
tbl.rows[i+1].cells[2].innerHTML = `${e.vlan}`;
|
tbl.rows[i+1].cells[2].innerHTML = `${e.vlan}`;
|
||||||
tbl.rows[i+1].cells[3].innerHTML = `${e.type}`;
|
tbl.rows[i+1].cells[3].innerHTML = `${e.type}`;
|
||||||
tbl.rows[i+1].cells[4].innerHTML = '<button type="button" onclick="delL2(' + e.idx + ');">' + t('l2_delete') + '</button>';
|
tbl.rows[i+1].cells[4].innerHTML = delL2Button(e);
|
||||||
} else {
|
} else {
|
||||||
const tr = tbl.insertRow();
|
const tr = tbl.insertRow();
|
||||||
let td = tr.insertCell(); td.innerHTML = `${e.port}`;
|
let td = tr.insertCell(); td.innerHTML = `${e.port}`;
|
||||||
td = tr.insertCell(); td.innerHTML = `${e.mac}`;
|
td = tr.insertCell(); td.innerHTML = `${e.mac}`;
|
||||||
td = tr.insertCell(); td.innerHTML = `${e.vlan}`;
|
td = tr.insertCell(); td.innerHTML = `${e.vlan}`;
|
||||||
td = tr.insertCell(); td.innerHTML = `${e.type}`;
|
td = tr.insertCell(); td.innerHTML = `${e.type}`;
|
||||||
td = tr.insertCell(); td.innerHTML = '<button type="button" onclick="delL2(' + e.idx + ');">' + t('l2_delete') + '</button>';
|
td = tr.insertCell(); td.innerHTML = delL2Button(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i = tbl.rows.length - 1; i > s.length; i--)
|
for (let i = tbl.rows.length - 1; i > s.length; i--)
|
||||||
|
|||||||
@@ -88,6 +88,8 @@
|
|||||||
<input style="width:20%;" class="action" id="cmd_sub" onclick="cmdSub();" type="button" data-i18n="sys_send_cmd" value="Send Command"><br/>
|
<input style="width:20%;" class="action" id="cmd_sub" onclick="cmdSub();" type="button" data-i18n="sys_send_cmd" value="Send Command"><br/>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<span data-i18n="sys_console_warn">Be careful when entering console commands, you can lock yourself out!</span><br/>
|
<span data-i18n="sys_console_warn">Be careful when entering console commands, you can lock yourself out!</span><br/>
|
||||||
|
<br/>
|
||||||
|
<pre id="console_out" style="height:22em;overflow:auto;white-space:pre-wrap;border:1px solid;padding:0.5em;"></pre>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+16
-2
@@ -35,14 +35,28 @@ async function ipSub() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function cmdSub() {
|
async function cmdSub() {
|
||||||
var cmd = document.getElementById('console_cmd').value;
|
const input = document.getElementById('console_cmd');
|
||||||
|
const out = document.getElementById('console_out');
|
||||||
|
const cmd = input.value;
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/cmd', {
|
const response = await fetch('/cmd', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: cmd
|
body: cmd
|
||||||
});
|
});
|
||||||
console.log('Completed!', response);
|
if (response.status == 401) {
|
||||||
|
window.location.href = 'login.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let text = await response.text();
|
||||||
|
if (text != "" && !text.endsWith("\n"))
|
||||||
|
text += "\n";
|
||||||
|
if (out.textContent.length > 20000)
|
||||||
|
out.textContent = out.textContent.slice(-16000);
|
||||||
|
out.textContent += "> " + cmd + "\n" + text;
|
||||||
|
out.scrollTop = out.scrollHeight;
|
||||||
|
input.value = "";
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
out.textContent += "> " + cmd + "\n" + err + "\n";
|
||||||
console.error(`Error: ${err}`);
|
console.error(`Error: ${err}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-4
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
extern volatile __xdata uint8_t sfr_data[4];
|
extern volatile __xdata uint8_t sfr_data[4];
|
||||||
extern volatile __xdata uint32_t ticks;
|
extern volatile __xdata uint32_t ticks;
|
||||||
|
extern __xdata uint8_t cmd_capture; /* owned by rtlplayground.c, see write_char_no_syslog() */
|
||||||
extern __code uint8_t * __code hex;
|
extern __code uint8_t * __code hex;
|
||||||
extern __code struct f_data f_data[];
|
extern __code struct f_data f_data[];
|
||||||
extern __code char * __code mime_strings[];
|
extern __code char * __code mime_strings[];
|
||||||
@@ -625,12 +626,29 @@ static void handle_firmware_fragment(__xdata uint8_t *p)
|
|||||||
|
|
||||||
static void run_cmd_body(__xdata uint8_t *body)
|
static void run_cmd_body(__xdata uint8_t *body)
|
||||||
{
|
{
|
||||||
|
uint16_t hdr_len = strtox(outbuf, HTTP_RESPONCE_TXT);
|
||||||
|
|
||||||
|
slen = hdr_len;
|
||||||
|
cmd_capture = 1;
|
||||||
execute_commands(body);
|
execute_commands(body);
|
||||||
|
if (cmd_capture == 2)
|
||||||
|
slen += strtox(outbuf + slen, CMD_TRUNCATED);
|
||||||
|
cmd_capture = 0;
|
||||||
|
/* Commands that configure something print nothing at all. Saying
|
||||||
|
* so beats an empty body, which reads the same as "nothing ran".
|
||||||
|
* Only on success: a silent failure must not answer with "OK". */
|
||||||
|
if (err_status == ERR_OK && slen == hdr_len)
|
||||||
|
slen += strtox(outbuf + slen, "OK\n");
|
||||||
|
/* On a parse error keep what the parser printed, because that text
|
||||||
|
* is the explanation, and only restate the status. "400 NO" is as
|
||||||
|
* long as "200 OK", so the header does not have to be rebuilt. */
|
||||||
if (err_status != ERR_OK) {
|
if (err_status != ERR_OK) {
|
||||||
send_bad_request();
|
outbuf[9] = '4';
|
||||||
return;
|
outbuf[10] = '0';
|
||||||
|
outbuf[11] = '0';
|
||||||
|
outbuf[13] = 'N';
|
||||||
|
outbuf[14] = 'O';
|
||||||
}
|
}
|
||||||
send_ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -824,7 +842,7 @@ void httpd_appcall(void)
|
|||||||
} else if (uip_closed()) {
|
} else if (uip_closed()) {
|
||||||
dbg_string("Connection closed\n");
|
dbg_string("Connection closed\n");
|
||||||
s->tstate = TSTATE_CLOSED;
|
s->tstate = TSTATE_CLOSED;
|
||||||
} else if (uip_aborted()) {
|
} else if (uip_aborted() || uip_timedout()) {
|
||||||
dbg_string("Connection aborted\n");
|
dbg_string("Connection aborted\n");
|
||||||
uip_close();
|
uip_close();
|
||||||
s->tstate = TSTATE_CLOSED;
|
s->tstate = TSTATE_CLOSED;
|
||||||
@@ -994,6 +1012,7 @@ void httpd_appcall(void)
|
|||||||
if (!authenticated && !(f_data[entry].start == FDATA_START_login_html
|
if (!authenticated && !(f_data[entry].start == FDATA_START_login_html
|
||||||
|| f_data[entry].start == FDATA_START_port_svg
|
|| f_data[entry].start == FDATA_START_port_svg
|
||||||
|| f_data[entry].start == FDATA_START_sfp_svg
|
|| f_data[entry].start == FDATA_START_sfp_svg
|
||||||
|
|| f_data[entry].start == FDATA_START_i18n_js
|
||||||
|| f_data[entry].start == FDATA_START_style_css)) {
|
|| f_data[entry].start == FDATA_START_style_css)) {
|
||||||
send_to_login();
|
send_to_login();
|
||||||
goto do_send;
|
goto do_send;
|
||||||
|
|||||||
+32
-21
@@ -48,7 +48,7 @@ extern __xdata char sfp_module_serial[2][17];
|
|||||||
extern __xdata uint8_t sfp_options[2];
|
extern __xdata uint8_t sfp_options[2];
|
||||||
|
|
||||||
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: application/json\r\n\r\n";
|
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: application/json\r\n\r\n";
|
||||||
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
|
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\n";
|
||||||
|
|
||||||
// Convert uint8_t to ascii HEX char push on html-buffer.
|
// Convert uint8_t to ascii HEX char push on html-buffer.
|
||||||
void charhex_to_html(char c)
|
void charhex_to_html(char c)
|
||||||
@@ -223,11 +223,12 @@ void send_basic_info(void)
|
|||||||
itoa_html(uip_netmask[0] >> 8); char_to_html('.');
|
itoa_html(uip_netmask[0] >> 8); char_to_html('.');
|
||||||
itoa_html(uip_netmask[1]); char_to_html('.');
|
itoa_html(uip_netmask[1]); char_to_html('.');
|
||||||
itoa_html(uip_netmask[1] >> 8);
|
itoa_html(uip_netmask[1] >> 8);
|
||||||
slen += strtox(outbuf + slen, "\",\"syslog_server_ip\":\"");
|
slen += strtox(outbuf + slen, "\",\"syslog_server\":\"");
|
||||||
itoa_html(syslog_state.server_ip[0]); char_to_html('.');
|
itoa_html(syslog_state.server_ip[0]); char_to_html('.');
|
||||||
itoa_html(syslog_state.server_ip[1]); char_to_html('.');
|
itoa_html(syslog_state.server_ip[1]); char_to_html('.');
|
||||||
itoa_html(syslog_state.server_ip[2]); char_to_html('.');
|
itoa_html(syslog_state.server_ip[2]); char_to_html('.');
|
||||||
itoa_html(syslog_state.server_ip[3]);
|
itoa_html(syslog_state.server_ip[3]); char_to_html(':');
|
||||||
|
itoa16_html(syslog_state.server_port);
|
||||||
slen += strtox(outbuf + slen, "\",\"mac_address\":\"");
|
slen += strtox(outbuf + slen, "\",\"mac_address\":\"");
|
||||||
byte_to_html(uip_ethaddr.addr[0]); char_to_html(':');
|
byte_to_html(uip_ethaddr.addr[0]); char_to_html(':');
|
||||||
byte_to_html(uip_ethaddr.addr[1]); char_to_html(':');
|
byte_to_html(uip_ethaddr.addr[1]); char_to_html(':');
|
||||||
@@ -432,42 +433,52 @@ void l2_delete(uint16_t idx)
|
|||||||
__xdata uint8_t entries_left = L2_MAX_TRANSFER;
|
__xdata uint8_t entries_left = L2_MAX_TRANSFER;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
reg_read_m(RTL837X_TBL_CTRL);
|
reg_read(RTL837X_TBL_CTRL);
|
||||||
} while (sfr_data[3] & TBL_EXECUTE);
|
} while (SFR_DATA_0 & TBL_EXECUTE);
|
||||||
slen += strtox(outbuf + slen, "{\"result\":");
|
slen += strtox(outbuf + slen, "{\"result\":");
|
||||||
// First, search for the entry based on the index
|
// First, search for the entry based on the index
|
||||||
reg_read_m(RTL837x_TBL_DATA_0);
|
reg_read_m(RTL837x_TBL_DATA_0);
|
||||||
REG_WRITE(RTL837x_TBL_DATA_0, sfr_data[0], sfr_data[1] & 0xfc, sfr_data[2] | (TBL_LUTREAD_NEXT_L2UC << 6), sfr_data[3]);
|
sfr_data[1] &= 0xfc;
|
||||||
|
sfr_data[2] |= (TBL_LUTREAD_NEXT_L2UC << 6);
|
||||||
|
reg_write_m(RTL837x_TBL_DATA_0);
|
||||||
|
|
||||||
REG_WRITE(RTL837X_TBL_CTRL, (idx >> 8) & 0xf, idx, TBL_L2_UNICAST, TBL_EXECUTE);
|
REG_WRITE(RTL837X_TBL_CTRL, (idx >> 8) & 0xf, idx, TBL_L2_UNICAST, TBL_EXECUTE);
|
||||||
do {
|
do {
|
||||||
reg_read_m(RTL837X_TBL_CTRL);
|
reg_read(RTL837X_TBL_CTRL);
|
||||||
} while (sfr_data[3] & 0x1);
|
} while (SFR_DATA_0 & 0x1);
|
||||||
reg_read_m(RTL837x_L2_DATA_OUT_B);
|
reg_read_m(RTL837x_L2_DATA_OUT_B);
|
||||||
if (!(sfr_data[0] & 0x20)) {
|
if (!(SFR_DATA_24 & 0x20)) {
|
||||||
char_to_html('0');
|
char_to_html('0');
|
||||||
} else {
|
} else {
|
||||||
|
__bit is_our_mac_addr = uip_ethaddr.addr[0] == SFR_DATA_8 && uip_ethaddr.addr[1] == SFR_DATA_0;
|
||||||
sfr_data[0] &= 0x3f; // Clear SPA
|
sfr_data[0] &= 0x3f; // Clear SPA
|
||||||
reg_write_m(RTL837x_TBL_DATA_IN_B);
|
reg_write_m(RTL837x_TBL_DATA_IN_B);
|
||||||
|
|
||||||
// Second half of MAC is copied
|
// Second half of MAC is copied
|
||||||
reg_read_m(RTL837x_L2_DATA_OUT_A);
|
reg_read_m(RTL837x_L2_DATA_OUT_A);
|
||||||
reg_write_m(RTL837x_TBL_DATA_IN_A);
|
if (is_our_mac_addr && uip_ethaddr.addr[2] == SFR_DATA_24 && uip_ethaddr.addr[3] == SFR_DATA_16
|
||||||
|
&& uip_ethaddr.addr[4] == SFR_DATA_8 && uip_ethaddr.addr[5] == SFR_DATA_0) {
|
||||||
|
// the switch's own entry keeps management reachable
|
||||||
|
char_to_html('0');
|
||||||
|
} else {
|
||||||
|
reg_write_m(RTL837x_TBL_DATA_IN_A);
|
||||||
|
|
||||||
reg_read_m(RTL837x_L2_DATA_OUT_C);
|
reg_read_m(RTL837x_L2_DATA_OUT_C);
|
||||||
sfr_data[3] &= 0xc0; // Clear age, auth and second part of ports
|
sfr_data[3] &= 0xc0; // Clear age, auth and second part of ports
|
||||||
sfr_data[1] &= 0xfe; // Clear nosalearn
|
sfr_data[1] &= 0xfe; // Clear nosalearn
|
||||||
reg_write_m(RTL837x_TBL_DATA_IN_C);
|
reg_write_m(RTL837x_TBL_DATA_IN_C);
|
||||||
|
|
||||||
reg_read_m(RTL837x_TBL_DATA_0);
|
reg_read_m(RTL837x_TBL_DATA_0);
|
||||||
REG_WRITE(RTL837x_TBL_DATA_0, sfr_data[0], sfr_data[1], TBL_L2_UNICAST, sfr_data[3]);
|
sfr_data[2] = TBL_L2_UNICAST;
|
||||||
|
reg_write_m(RTL837x_TBL_DATA_0);
|
||||||
|
|
||||||
REG_WRITE(RTL837X_TBL_CTRL, idx >> 8, idx, TBL_L2_UNICAST, TBL_WRITE | TBL_EXECUTE);
|
REG_WRITE(RTL837X_TBL_CTRL, idx >> 8, idx, TBL_L2_UNICAST, TBL_WRITE | TBL_EXECUTE);
|
||||||
do {
|
do {
|
||||||
reg_read_m(RTL837X_TBL_CTRL);
|
reg_read(RTL837X_TBL_CTRL);
|
||||||
} while (sfr_data[3] & TBL_EXECUTE);
|
} while (SFR_DATA_0 & TBL_EXECUTE);
|
||||||
|
|
||||||
char_to_html('1');
|
char_to_html('1');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
char_to_html('}');
|
char_to_html('}');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
extern __code uint8_t * __code HTTP_RESPONCE_TXT;
|
||||||
|
|
||||||
bool send_counters(uint8_t phys_port);
|
bool send_counters(uint8_t phys_port);
|
||||||
void send_status(void);
|
void send_status(void);
|
||||||
void send_vlan(uint16_t vlan);
|
void send_vlan(uint16_t vlan);
|
||||||
|
|||||||
@@ -487,6 +487,7 @@ __code const struct machine machine = {
|
|||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "Lianguo ZX-SWTGW215AS",
|
.machine_name = "Lianguo ZX-SWTGW215AS",
|
||||||
.isRTL8373 = 0,
|
.isRTL8373 = 0,
|
||||||
|
.mac_flash_offset = 0x1FC000,
|
||||||
.min_port = 3,
|
.min_port = 3,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
.n_sfp = 1,
|
.n_sfp = 1,
|
||||||
@@ -801,9 +802,13 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif defined MACHINE_FNS1200P
|
#elif defined(MACHINE_PCB_K0402WS_V2) || defined(MACHINE_FNS1200P)
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
|
#if defined(MACHINE_PCB_K0402WS_V2)
|
||||||
|
.machine_name = "PCB-K0402WS-V2.0",
|
||||||
|
#else
|
||||||
.machine_name = "FNS-1200P",
|
.machine_name = "FNS-1200P",
|
||||||
|
#endif
|
||||||
.isRTL8373 = 0,
|
.isRTL8373 = 0,
|
||||||
.min_port = 3,
|
.min_port = 3,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
// #define MACHINE_SWTGW218AS
|
// #define MACHINE_SWTGW218AS
|
||||||
// #define MACHINE_PCB_SWTG018AS_V2_1_0
|
// #define MACHINE_PCB_SWTG018AS_V2_1_0
|
||||||
// #define MACHINE_PCB_K0402WS_V3
|
// #define MACHINE_PCB_K0402WS_V3
|
||||||
|
// #define MACHINE_PCB_K0402WS_V2
|
||||||
// #define MACHINE_K0501W_V2_0
|
// #define MACHINE_K0501W_V2_0
|
||||||
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
|
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
|
||||||
// #define MACHINE_ZX310S_4T2XH
|
// #define MACHINE_ZX310S_4T2XH
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ void machine_custom_init(void) __banked
|
|||||||
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined MACHINE_FNS1200P
|
#elif defined(MACHINE_PCB_K0402WS_V2) || defined(MACHINE_FNS1200P)
|
||||||
void machine_custom_init(void) __banked
|
void machine_custom_init(void) __banked
|
||||||
{
|
{
|
||||||
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ extern __xdata uint8_t sbuf[SBUF_SIZE];
|
|||||||
// Size of the TCP Output buffer
|
// Size of the TCP Output buffer
|
||||||
#define TCP_OUTBUF_SIZE 2500
|
#define TCP_OUTBUF_SIZE 2500
|
||||||
|
|
||||||
|
// Appended when a captured command wrote more than the output buffer holds,
|
||||||
|
// so a clipped listing is visibly clipped instead of silently short.
|
||||||
|
#define CMD_TRUNCATED "\n[output truncated]\n"
|
||||||
|
|
||||||
// Size of the port name, including the terminating null byte
|
// Size of the port name, including the terminating null byte
|
||||||
#define PORT_NAME_SIZE 32
|
#define PORT_NAME_SIZE 32
|
||||||
|
|
||||||
@@ -138,6 +142,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_short(uint16_t v);
|
||||||
void print_sfr_data(void);
|
void print_sfr_data(void);
|
||||||
void print_phy_data(void);
|
void print_phy_data(void);
|
||||||
void print_cmd_prompt(void);
|
void print_cmd_prompt(void);
|
||||||
|
|||||||
@@ -911,3 +911,57 @@ bool port_ingress_vlan_filter_get(uint8_t port) __banked
|
|||||||
|
|
||||||
return reg_bit_test(RTL837X_VLAN_PORT_IGR_FLTR, port);
|
return reg_bit_test(RTL837X_VLAN_PORT_IGR_FLTR, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// C1 bit 0: static (no aging); age at C3[4:2] must be non-zero or the
|
||||||
|
// entry is invisible to lookup
|
||||||
|
static void l2_mgmt_entry_fill(__xdata uint8_t *mac, __xdata uint16_t vlan)
|
||||||
|
{
|
||||||
|
REG_WRITE(RTL837x_TBL_DATA_IN_A, mac[2], mac[3], mac[4], mac[5]);
|
||||||
|
REG_WRITE(RTL837x_TBL_DATA_IN_B, 0x20 | ((CPU_PORT & 0x3) << 6) | (vlan >> 8),
|
||||||
|
vlan & 0xff, mac[0], mac[1]);
|
||||||
|
REG_WRITE(RTL837x_TBL_DATA_IN_C, 0x00, 0x01, 0x00, (7 << 2) | (CPU_PORT >> 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void l2_mgmt_tbl_prepare(void)
|
||||||
|
{
|
||||||
|
reg_read_m(RTL837x_TBL_DATA_0);
|
||||||
|
sfr_data[2] &= 0x3f;
|
||||||
|
sfr_data[1] &= 0xf8;
|
||||||
|
reg_write_m(RTL837x_TBL_DATA_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wait_table_ready(void)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
reg_read(RTL837X_TBL_CTRL);
|
||||||
|
} while (SFR_DATA_0 & TBL_EXECUTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Pin the management MAC to the CPU port; remove_entry deletes it */
|
||||||
|
void port_l2_static_mgmt(__xdata uint8_t *mac, __xdata uint16_t vlan, __xdata bool remove_entry) __banked
|
||||||
|
{
|
||||||
|
wait_table_ready();
|
||||||
|
|
||||||
|
// vlan 0 = management VLAN disabled: untagged management resolves in
|
||||||
|
// VLAN 1; clients in other VLANs keep their learned entry and age as before
|
||||||
|
if (!vlan)
|
||||||
|
vlan = 1;
|
||||||
|
l2_mgmt_entry_fill(mac, vlan);
|
||||||
|
l2_mgmt_tbl_prepare();
|
||||||
|
if (remove_entry) {
|
||||||
|
// a search miss returns index 0, not a slot
|
||||||
|
REG_WRITE(RTL837X_TBL_CTRL, 0x00, 0x00, TBL_L2_UNICAST, TBL_EXECUTE);
|
||||||
|
wait_table_ready();
|
||||||
|
reg_read_m(RTL837x_TBL_DATA_0);
|
||||||
|
if (!(sfr_data[2] & 0x10))
|
||||||
|
return;
|
||||||
|
sfr_data[1] |= 0x04; // CLEAR-entry
|
||||||
|
reg_write_m(RTL837x_TBL_DATA_0);
|
||||||
|
__xdata uint16_t idx = (((uint16_t)sfr_data[2] & 0x0f) << 8) | sfr_data[3];
|
||||||
|
REG_WRITE(RTL837X_TBL_CTRL, idx >> 8, idx & 0xff, TBL_L2_UNICAST, TBL_WRITE | TBL_EXECUTE);
|
||||||
|
} else {
|
||||||
|
// method-0 write: the hardware hashes the key and places the entry
|
||||||
|
REG_WRITE(RTL837X_TBL_CTRL, 0x00, 0x00, TBL_L2_UNICAST, TBL_WRITE | TBL_EXECUTE);
|
||||||
|
}
|
||||||
|
wait_table_ready();
|
||||||
|
}
|
||||||
@@ -81,5 +81,6 @@ bool port_ingress_vlan_filter_get(uint8_t port) __banked;
|
|||||||
vlan_ingress_mode_t port_ingress_filter_get(__xdata uint8_t port) __banked;
|
vlan_ingress_mode_t port_ingress_filter_get(__xdata uint8_t port) __banked;
|
||||||
void port_isolate(uint8_t port, __xdata uint16_t pmask) __banked;
|
void port_isolate(uint8_t port, __xdata uint16_t pmask) __banked;
|
||||||
uint16_t port_isolation_get(uint8_t port) __banked;
|
uint16_t port_isolation_get(uint8_t port) __banked;
|
||||||
|
void port_l2_static_mgmt(__xdata uint8_t *mac, __xdata uint16_t vlan, __xdata bool remove_entry) __banked;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -240,8 +240,25 @@ void isr_serial(void) __interrupt(4)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Set by the httpd while it runs a command that arrived over the network, so
|
||||||
|
* that everything the command prints lands in the response as well. */
|
||||||
|
__xdata uint8_t cmd_capture;
|
||||||
|
extern __xdata uint8_t outbuf[TCP_OUTBUF_SIZE];
|
||||||
|
extern __xdata uint16_t slen;
|
||||||
|
|
||||||
void write_char_no_syslog(char c)
|
void write_char_no_syslog(char c)
|
||||||
{
|
{
|
||||||
|
/* Capturing sits here rather than in write_char() so that the messages
|
||||||
|
* printed through print_string_no_syslog() are captured too: those are
|
||||||
|
* the replies of the syslog commands, which must not generate a syslog
|
||||||
|
* packet but do belong in the answer to a command sent over HTTP. */
|
||||||
|
if (cmd_capture) {
|
||||||
|
if (slen < TCP_OUTBUF_SIZE - sizeof(CMD_TRUNCATED))
|
||||||
|
outbuf[slen++] = c;
|
||||||
|
else
|
||||||
|
cmd_capture = 2; /* out of room, httpd says so */
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
} while (tx_buf_empty == 0);
|
} while (tx_buf_empty == 0);
|
||||||
if (c =='\n') {
|
if (c =='\n') {
|
||||||
@@ -282,6 +299,32 @@ void itoa(uint8_t v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Same as itoa(), one decade wider: enough for a port number. Kept separate
|
||||||
|
* rather than widening itoa() itself, because every existing caller passes a
|
||||||
|
* byte and would start paying for 16-bit divisions it does not need. */
|
||||||
|
void itoa_short(uint16_t v)
|
||||||
|
{
|
||||||
|
uint8_t t = v / 10000;
|
||||||
|
uint8_t print_zeros = t;
|
||||||
|
|
||||||
|
if (print_zeros)
|
||||||
|
write_char('0' + t);
|
||||||
|
t = (v / 1000) % 10;
|
||||||
|
print_zeros |= t;
|
||||||
|
if (print_zeros)
|
||||||
|
write_char('0' + t);
|
||||||
|
t = (v / 100) % 10;
|
||||||
|
print_zeros |= t;
|
||||||
|
if (print_zeros)
|
||||||
|
write_char('0' + t);
|
||||||
|
t = (v / 10) % 10;
|
||||||
|
print_zeros |= t;
|
||||||
|
if (print_zeros)
|
||||||
|
write_char('0' + t);
|
||||||
|
write_char('0' + (v % 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void print_string(__code char *p)
|
void print_string(__code char *p)
|
||||||
{
|
{
|
||||||
while (*p)
|
while (*p)
|
||||||
@@ -2306,6 +2349,8 @@ void main(void)
|
|||||||
early_boot_handle_button();
|
early_boot_handle_button();
|
||||||
|
|
||||||
execute_config();
|
execute_config();
|
||||||
|
// After the config so the entry lands in the final management VLAN
|
||||||
|
port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, false);
|
||||||
/* After the config: a name from it wins, otherwise derive one. */
|
/* After the config: a name from it wins, otherwise derive one. */
|
||||||
set_hostname_default();
|
set_hostname_default();
|
||||||
print_cmd_prompt();
|
print_cmd_prompt();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "syslog.h"
|
#include "syslog.h"
|
||||||
|
#include "cmd_parser.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
|
|
||||||
@@ -22,20 +23,21 @@ void syslog_init(void) __banked
|
|||||||
state.readptr = 0;
|
state.readptr = 0;
|
||||||
state.line_available = 0;
|
state.line_available = 0;
|
||||||
state.server_ip[0] = 0; state.server_ip[1] = 0; state.server_ip[2] = 0; state.server_ip[3] = 0;// Default to 0.0.0.0
|
state.server_ip[0] = 0; state.server_ip[1] = 0; state.server_ip[2] = 0; state.server_ip[3] = 0;// Default to 0.0.0.0
|
||||||
|
state.server_port = SYSLOG_PORT_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void syslog_start(void) __banked
|
void syslog_start(void) __banked
|
||||||
{
|
{
|
||||||
if (state.syslog_conn == 0) {
|
if (state.syslog_conn == 0) {
|
||||||
uip_ipaddr(server_ip, state.server_ip[0], state.server_ip[1], state.server_ip[2], state.server_ip[3]);
|
uip_ipaddr(server_ip, state.server_ip[0], state.server_ip[1], state.server_ip[2], state.server_ip[3]);
|
||||||
state.syslog_conn = uip_udp_new(&server_ip, HTONS(514));
|
state.syslog_conn = uip_udp_new(&server_ip, HTONS(state.server_port));
|
||||||
if (state.syslog_conn == 0) {
|
if (state.syslog_conn == 0) {
|
||||||
print_string_newline_no_syslog("Failed to create a new UDP client");
|
print_string_newline_no_syslog("Failed to create a new UDP client");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
print_string_newline_no_syslog("Started syslog to IP ");
|
print_string_newline_no_syslog("Started syslog to IP ");
|
||||||
itoa(state.server_ip[0]); write_char('.'); itoa(state.server_ip[1]); write_char('.');
|
print_ip(state.server_ip);
|
||||||
itoa(state.server_ip[2]); write_char('.'); itoa(state.server_ip[3]); write_char('\n');
|
write_char(':'); itoa_short(state.server_port); write_char('\n');
|
||||||
state.enabled = 1;
|
state.enabled = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -57,6 +59,7 @@ void syslog_stop(void) __banked
|
|||||||
|
|
||||||
void syslog_callback(uint16_t lport) __banked
|
void syslog_callback(uint16_t lport) __banked
|
||||||
{
|
{
|
||||||
|
uint16_t syslog_hdr;
|
||||||
if (lport != state.syslog_conn->lport)
|
if (lport != state.syslog_conn->lport)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -91,14 +94,31 @@ void syslog_callback(uint16_t lport) __banked
|
|||||||
|
|
||||||
memcpyc(SYSLOG_P, "<14>", 4); // Syslog priority prefix
|
memcpyc(SYSLOG_P, "<14>", 4); // Syslog priority prefix
|
||||||
|
|
||||||
if (log_end < log_start) {
|
/* RFC 3164 puts a hostname between the priority and the text, and
|
||||||
memcpy(SYSLOG_P + 4, logbuf + log_start, LOGBUF_SIZE - log_start);
|
* we were leaving that slot empty. A receiver still has to fill
|
||||||
memcpy(SYSLOG_P + 4 + LOGBUF_SIZE - log_start, logbuf, log_end);
|
* the field, so it takes the first word of the message instead:
|
||||||
|
* every line arrives attributed to "STP:" or "REGGET:" or
|
||||||
|
* whatever the log happens to start with, and the sender cannot
|
||||||
|
* be selected on at all. Send our own name and the field means
|
||||||
|
* something. Skipped when the name is empty, so we never emit a
|
||||||
|
* lone separator. */
|
||||||
|
syslog_hdr = strlen_x(hostname);
|
||||||
|
if (syslog_hdr) {
|
||||||
|
memcpy(SYSLOG_P + 4, hostname, syslog_hdr);
|
||||||
|
SYSLOG_P[4 + syslog_hdr] = ' ';
|
||||||
|
syslog_hdr += 5;
|
||||||
} else {
|
} else {
|
||||||
memcpy(SYSLOG_P + 4, logbuf + log_start, log_end - log_start);
|
syslog_hdr = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
uip_udp_send(log_size+4);
|
if (log_end < log_start) {
|
||||||
|
memcpy(SYSLOG_P + syslog_hdr, logbuf + log_start, LOGBUF_SIZE - log_start);
|
||||||
|
memcpy(SYSLOG_P + syslog_hdr + LOGBUF_SIZE - log_start, logbuf, log_end);
|
||||||
|
} else {
|
||||||
|
memcpy(SYSLOG_P + syslog_hdr, logbuf + log_start, log_end - log_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
uip_udp_send(log_size + syslog_hdr);
|
||||||
state.readptr = state.writeptr;
|
state.readptr = state.writeptr;
|
||||||
state.line_available = 0;
|
state.line_available = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
#ifndef _SYSLOG_H_
|
#ifndef _SYSLOG_H_
|
||||||
#define _SYSLOG_H_
|
#define _SYSLOG_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define LOGBUF_SIZE 512
|
#define LOGBUF_SIZE 512
|
||||||
|
|
||||||
|
#define SYSLOG_PORT_DEFAULT 514
|
||||||
|
|
||||||
struct syslog_state {
|
struct syslog_state {
|
||||||
uint8_t enabled;
|
bool enabled;
|
||||||
uint8_t line_available;
|
uint8_t line_available;
|
||||||
uint16_t writeptr ;
|
uint16_t writeptr ;
|
||||||
uint16_t readptr;
|
uint16_t readptr;
|
||||||
uint8_t server_ip[4];
|
uint8_t server_ip[4];
|
||||||
|
uint16_t server_port;
|
||||||
|
|
||||||
struct uip_udp_conn *syslog_conn;
|
struct uip_udp_conn *syslog_conn;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -96,6 +96,21 @@ typedef unsigned short uip_stats_t;
|
|||||||
*/
|
*/
|
||||||
#define UIP_CONF_MAX_CONNECTIONS 1
|
#define UIP_CONF_MAX_CONNECTIONS 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This httpd closes after every response, so an ESTABLISHED connection
|
||||||
|
* that stays idle is a peer that died or never sent its request. With a
|
||||||
|
* single connection slot it would hold the web UI until the next power
|
||||||
|
* cycle, so it is aged out instead.
|
||||||
|
*
|
||||||
|
* uip_periodic() runs from idle() once per system tick; interrupt
|
||||||
|
* wake-ups only add sweeps, so the timeout can fire early but never
|
||||||
|
* late.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#define UIP_CONF_IDLE_PERIODS 200
|
||||||
|
#define UIP_CONF_IDLE_TIMEOUT 30
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of listening TCP ports. TODO: increase this!
|
* Maximum number of listening TCP ports. TODO: increase this!
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -171,6 +171,11 @@ __xdata struct uip_udp_conn * __xdata uip_udp_conn;
|
|||||||
__xdata struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
|
__xdata struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
|
|
||||||
|
#if UIP_IDLE_TIMEOUT
|
||||||
|
__xdata static u8_t uip_idle_prescale;
|
||||||
|
__xdata static u8_t uip_idle_age;
|
||||||
|
#endif /* UIP_IDLE_TIMEOUT */
|
||||||
|
|
||||||
__xdata static u16_t ipid; /* Ths ipid variable is an increasing
|
__xdata static u16_t ipid; /* Ths ipid variable is an increasing
|
||||||
number that is used for the IP ID
|
number that is used for the IP ID
|
||||||
field. */
|
field. */
|
||||||
@@ -702,6 +707,15 @@ 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_IDLE_TIMEOUT
|
||||||
|
if(uip_connr == uip_conns) {
|
||||||
|
uip_idle_age = 0;
|
||||||
|
if(++uip_idle_prescale >= UIP_IDLE_PERIODS) {
|
||||||
|
uip_idle_prescale = 0;
|
||||||
|
uip_idle_age = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* UIP_IDLE_TIMEOUT */
|
||||||
#if UIP_REASSEMBLY
|
#if UIP_REASSEMBLY
|
||||||
if(uip_reasstmr != 0) {
|
if(uip_reasstmr != 0) {
|
||||||
--uip_reasstmr;
|
--uip_reasstmr;
|
||||||
@@ -733,6 +747,21 @@ uip_process(u8_t flag) __banked
|
|||||||
/* If the connection has outstanding data, we increase the
|
/* If the connection has outstanding data, we increase the
|
||||||
connection's timer and see if it has reached the RTO value
|
connection's timer and see if it has reached the RTO value
|
||||||
in which case we retransmit. */
|
in which case we retransmit. */
|
||||||
|
#if UIP_IDLE_TIMEOUT
|
||||||
|
if(!uip_outstanding(uip_connr)) {
|
||||||
|
/* The retransmission timer is unused while nothing is in flight,
|
||||||
|
so idle time is counted in it instead. */
|
||||||
|
if(uip_idle_age &&
|
||||||
|
(uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
|
||||||
|
++(uip_connr->timer) >= UIP_IDLE_TIMEOUT) {
|
||||||
|
uip_connr->tcpstateflags = UIP_CLOSED;
|
||||||
|
uip_flags = UIP_TIMEDOUT;
|
||||||
|
UIP_APPCALL();
|
||||||
|
BUF->flags = TCP_RST | TCP_ACK;
|
||||||
|
goto tcp_send_nodata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* UIP_IDLE_TIMEOUT */
|
||||||
if(uip_outstanding(uip_connr)) {
|
if(uip_outstanding(uip_connr)) {
|
||||||
if(uip_connr->timer-- == 0) {
|
if(uip_connr->timer-- == 0) {
|
||||||
if(uip_connr->nrtx == UIP_MAXRTX ||
|
if(uip_connr->nrtx == UIP_MAXRTX ||
|
||||||
@@ -1550,6 +1579,11 @@ uip_process(u8_t flag) __banked
|
|||||||
#endif /* UIP_ACTIVE_OPEN */
|
#endif /* UIP_ACTIVE_OPEN */
|
||||||
|
|
||||||
case UIP_ESTABLISHED:
|
case UIP_ESTABLISHED:
|
||||||
|
#if UIP_IDLE_TIMEOUT
|
||||||
|
if(!uip_outstanding(uip_connr)) {
|
||||||
|
uip_connr->timer = 0;
|
||||||
|
}
|
||||||
|
#endif /* UIP_IDLE_TIMEOUT */
|
||||||
/* In the ESTABLISHED state, we call upon the application to feed
|
/* In the ESTABLISHED state, we call upon the application to feed
|
||||||
data into the uip_buf. If the UIP_ACKDATA flag is set, the
|
data into the uip_buf. If the UIP_ACKDATA flag is set, the
|
||||||
application should put new data into the buffer, otherwise we are
|
application should put new data into the buffer, otherwise we are
|
||||||
@@ -1576,6 +1610,9 @@ uip_process(u8_t flag) __banked
|
|||||||
uip_connr->len = 1;
|
uip_connr->len = 1;
|
||||||
uip_connr->tcpstateflags = UIP_LAST_ACK;
|
uip_connr->tcpstateflags = UIP_LAST_ACK;
|
||||||
uip_connr->nrtx = 0;
|
uip_connr->nrtx = 0;
|
||||||
|
#if UIP_IDLE_TIMEOUT
|
||||||
|
uip_connr->timer = uip_connr->rto;
|
||||||
|
#endif /* UIP_IDLE_TIMEOUT */
|
||||||
tcp_send_finack:
|
tcp_send_finack:
|
||||||
BUF->flags = TCP_FIN | TCP_ACK;
|
BUF->flags = TCP_FIN | TCP_ACK;
|
||||||
goto tcp_send_nodata;
|
goto tcp_send_nodata;
|
||||||
@@ -1665,6 +1702,9 @@ uip_process(u8_t flag) __banked
|
|||||||
uip_connr->len = 1;
|
uip_connr->len = 1;
|
||||||
uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
|
uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
|
||||||
uip_connr->nrtx = 0;
|
uip_connr->nrtx = 0;
|
||||||
|
#if UIP_IDLE_TIMEOUT
|
||||||
|
uip_connr->timer = uip_connr->rto;
|
||||||
|
#endif /* UIP_IDLE_TIMEOUT */
|
||||||
BUF->flags = TCP_FIN | TCP_ACK;
|
BUF->flags = TCP_FIN | TCP_ACK;
|
||||||
goto tcp_send_nodata;
|
goto tcp_send_nodata;
|
||||||
}
|
}
|
||||||
@@ -1693,6 +1733,9 @@ uip_process(u8_t flag) __banked
|
|||||||
/* Remember how much data we send out now so that we know
|
/* Remember how much data we send out now so that we know
|
||||||
when everything has been acknowledged. */
|
when everything has been acknowledged. */
|
||||||
uip_connr->len = uip_slen;
|
uip_connr->len = uip_slen;
|
||||||
|
#if UIP_IDLE_TIMEOUT
|
||||||
|
uip_connr->timer = uip_connr->rto;
|
||||||
|
#endif /* UIP_IDLE_TIMEOUT */
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* If the application already had unacknowledged data, we
|
/* If the application already had unacknowledged data, we
|
||||||
|
|||||||
@@ -324,6 +324,35 @@
|
|||||||
*/
|
*/
|
||||||
#define UIP_TIME_WAIT_TIMEOUT 120
|
#define UIP_TIME_WAIT_TIMEOUT 120
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of UIP_TIMER sweeps that make one idle-aging period,
|
||||||
|
* i.e. how many times uip_periodic() runs per second in this project.
|
||||||
|
* Counted in an 8-bit variable, so 255 is the maximum.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#ifndef UIP_CONF_IDLE_PERIODS
|
||||||
|
#define UIP_IDLE_PERIODS 2
|
||||||
|
#else /* UIP_CONF_IDLE_PERIODS */
|
||||||
|
#define UIP_IDLE_PERIODS UIP_CONF_IDLE_PERIODS
|
||||||
|
#endif /* UIP_CONF_IDLE_PERIODS */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of idle-aging periods after which an ESTABLISHED
|
||||||
|
* connection with a silent peer is aborted, or 0 to keep such
|
||||||
|
* connections forever (the classic uIP behaviour). TCP itself has no
|
||||||
|
* idle timeout, so a peer that vanished without FIN or RST would
|
||||||
|
* otherwise occupy its connection slot until a reboot. Counted in the
|
||||||
|
* connection's 8-bit retransmission timer, so 255 is the maximum.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#ifndef UIP_CONF_IDLE_TIMEOUT
|
||||||
|
#define UIP_IDLE_TIMEOUT 0
|
||||||
|
#else /* UIP_CONF_IDLE_TIMEOUT */
|
||||||
|
#define UIP_IDLE_TIMEOUT UIP_CONF_IDLE_TIMEOUT
|
||||||
|
#endif /* UIP_CONF_IDLE_TIMEOUT */
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/*------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------*/
|
||||||
|
|||||||
Reference in new issue
Block a user