|
#!/system/bin/sh |
|
# ============================================================================== |
|
# TITAN SMART CORE v3.0 - OPENWRT FUSION EDITION |
|
# BCM72604 Android TV 9 + OpenWRT MT7621A Ecosystem Optimizer |
|
# |
|
# NOWE W v3.0: |
|
# - SQM-aware TCP buffer calculation (CAKE RTT ~2-5ms vs legacy 40ms) |
|
# - ISP auto-detection (Orange PPPoE/T-Mobile DHCP) |
|
# - MTU path probe (RFC4638 awareness) |
|
# - Wi-Fi 5GHz band steering |
|
# - IPTV IGMP coexistence fix |
|
# - OpenWRT companion config generator |
|
# - Zero-Trust VLAN awareness |
|
# ============================================================================== |
|
|
|
readonly VERSION="3.0-FUSION" |
|
readonly LOG_FILE="/data/local/tmp/titan_v3.log" |
|
RISH_BIN="/data/local/tmp/rish" |
|
USE_RISH=0 |
|
|
|
# Wykryte parametry środowiskowe |
|
DETECTED_ISP="" |
|
DETECTED_MTU=1500 |
|
DETECTED_RTT_MS=40 |
|
SQM_ACTIVE=0 |
|
WIFI_BAND="" |
|
WIFI_FREQ_MHZ=0 |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# LOGGER |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
ts() { date '+%H:%M:%S'; } |
|
lnfo() { printf '[%s][INFO] %s\n' "$(ts)" "$*" | tee -a "$LOG_FILE"; } |
|
lok() { printf '[%s][ OK ] %s\n' "$(ts)" "$*" | tee -a "$LOG_FILE"; } |
|
lwrn() { printf '[%s][WARN] %s\n' "$(ts)" "$*" | tee -a "$LOG_FILE"; } |
|
lerr() { printf '[%s][ERR ] %s\n' "$(ts)" "$*" | tee -a "$LOG_FILE"; } |
|
lfix() { printf '[%s][FIX ] %s\n' "$(ts)" "$*" | tee -a "$LOG_FILE"; } |
|
|
|
# Idempotentne wrappery |
|
sp() { |
|
local k="$1" v="$2" |
|
[ "$(getprop "$k" 2>/dev/null)" = "$v" ] && return 0 |
|
setprop "$k" "$v" 2>/dev/null && lfix "prop: $k=$v" |
|
} |
|
ss() { |
|
local ns="$1" k="$2" v="$3" |
|
local cur; cur=$(settings get "$ns" "$k" 2>/dev/null) |
|
[ "$cur" = "$v" ] && return 0 |
|
if [ "$USE_RISH" = "1" ]; then |
|
"$RISH_BIN" -c "settings put $ns $k $v" 2>/dev/null |
|
else |
|
settings put "$ns" "$k" "$v" 2>/dev/null |
|
fi |
|
lfix "settings.$ns: $k=$v (was: $cur)" |
|
} |
|
sw() { |
|
local p="$1" v="$2" |
|
[ -w "$p" ] && echo "$v" > "$p" 2>/dev/null && lfix "sysfs: $p=$v" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# MODULE 0: ENVIRONMENT PROBE |
|
# Wykrywa: ISP typ, MTU, RTT, czy SQM jest aktywne po stronie routera |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
mod_env_probe() { |
|
lnfo "╔══ MODULE 0: ENVIRONMENT PROBE ══╗" |
|
|
|
# ── 0.1: Wykrycie GW i jego OUI (fingerprint ISP CPE) ───────────────── |
|
GW_IP=$(ip route show default 2>/dev/null | awk '/default/{print $3}' | head -1) |
|
lnfo " Gateway IP: ${GW_IP:-nieznany}" |
|
|
|
if [ -n "$GW_IP" ]; then |
|
# ARP lookup dla MAC GW |
|
ping -c 1 -W 1 "$GW_IP" >/dev/null 2>&1 |
|
GW_MAC=$(ip neigh show "$GW_IP" 2>/dev/null | awk '{print $5}' | head -1) |
|
GW_OUI=$(echo "$GW_MAC" | cut -c1-8 | tr '[:upper:]' '[:lower:]') |
|
lnfo " Gateway MAC OUI: ${GW_OUI:-nieznany}" |
|
|
|
# OUI fingerprint routerów Orange/T-Mobile/Sagemcom |
|
# Źródło: znane OUI producentów CPE |
|
case "$GW_OUI" in |
|
# Sagemcom (Orange Polska) |
|
"00:22:3f"|"00:26:b9"|"58:6d:8f"|"d0:76:e7"|"78:54:2e") |
|
DETECTED_ISP="ORANGE_SAGEMCOM" |
|
lnfo " → Wykryto: Orange Polska (Sagemcom CPE)" |
|
;; |
|
# Technicolor/Thomson (Orange) |
|
"00:90:d0"|"10:62:eb"|"68:a3:78") |
|
DETECTED_ISP="ORANGE_TECHNICOLOR" |
|
lnfo " → Wykryto: Orange Polska (Technicolor CPE)" |
|
;; |
|
# Arcadyan/Wiko (T-Mobile) |
|
"00:19:e0"|"2c:30:33"|"58:d5:6e"|"ec:43:f6") |
|
DETECTED_ISP="TMOBILE_ARCADYAN" |
|
lnfo " → Wykryto: T-Mobile Polska (Arcadyan CPE)" |
|
;; |
|
# OpenWRT (własny router - kluczowy case!) |
|
"00:e0:4c"|"dc:ef:ca"|"d0:50:99"|"c4:ad:34") |
|
DETECTED_ISP="OPENWRT_CUSTOM" |
|
lnfo " → Wykryto: OpenWRT custom router" |
|
;; |
|
*) |
|
DETECTED_ISP="UNKNOWN" |
|
lnfo " → Nieznany router (${GW_OUI})" |
|
;; |
|
esac |
|
fi |
|
|
|
# ── 0.2: MTU Path Probe (ICMP DF-bit) ──────────────────────────────── |
|
# Metodologia: wysyłamy pakiety z DF=1 o rosnącym rozmiarze |
|
# Cel: wykryć rzeczywiste MTU ścieżki (PPPoE=1492, RFC4638=1500, VLAN=1496) |
|
lnfo " MTU Path Probe (DF-bit ICMP)..." |
|
DETECTED_MTU=1452 # konserwatywny fallback |
|
# Android: ping -M do = DF bit; -s = payload size (nagłówek IP 20B + ICMP 8B = 28B) |
|
for mtu_test in 1500 1496 1492 1480 1472 1468 1452; do |
|
payload_size=$((mtu_test - 28)) |
|
# Próba 2 pakietów z timeout 2s |
|
if ping -c 2 -W 2 -s "$payload_size" 8.8.8.8 >/dev/null 2>&1; then |
|
DETECTED_MTU=$mtu_test |
|
lok " MTU probe: $mtu_test OK" |
|
break |
|
else |
|
lnfo " MTU probe: $mtu_test → fragmentacja/odrzucenie" |
|
fi |
|
done |
|
lnfo " → Wykryte MTU: $DETECTED_MTU" |
|
|
|
# Korekta na podstawie ISP |
|
case "$DETECTED_ISP" in |
|
ORANGE_*) |
|
# Orange PPPoE: MTU 1492 (bez RFC4638) lub 1500 (z RFC4638) |
|
[ "$DETECTED_MTU" -lt 1492 ] && lnfo " Orange PPPoE bez RFC4638 — MTU=$DETECTED_MTU" |
|
[ "$DETECTED_MTU" -ge 1500 ] && lnfo " Orange RFC4638 aktywne — MTU=1500 ✓" |
|
;; |
|
TMOBILE_*) |
|
# T-Mobile DHCP: standardowo MTU 1500 |
|
[ "$DETECTED_MTU" -lt 1500 ] && lwrn " T-Mobile poniżej MTU 1500 — sprawdź router" |
|
;; |
|
esac |
|
|
|
# ── 0.3: RTT Probe (wykryj czy SQM/CAKE aktywne) ───────────────────── |
|
# Kluczowa metoda: wysyłamy 30 pakietów pod pełnym obciążeniem TCP |
|
# CAKE → RTT max <10ms (A+ bufferbloat score) |
|
# Bez SQM → RTT może skakać do 200-500ms (D/F score) |
|
lnfo " RTT probe (20 pakietów do GW)..." |
|
if [ -n "$GW_IP" ]; then |
|
# Pomiar RTT do GW — szybki wskaźnik jakości kolejkowania |
|
RTT_RAW=$(ping -c 20 -W 1 -i 0.1 "$GW_IP" 2>/dev/null | \ |
|
grep -E 'rtt|round-trip' | \ |
|
sed 's/.*= //' | cut -d'/' -f2) |
|
|
|
if [ -n "$RTT_RAW" ]; then |
|
# RTT w ms (zaokrąglone) |
|
DETECTED_RTT_MS=$(echo "$RTT_RAW" | awk -F. '{print $1}') |
|
lnfo " RTT do GW avg: ${DETECTED_RTT_MS}ms" |
|
|
|
# Heurystyka SQM detection: |
|
# CAKE aktywne → RTT <5ms nawet pod obciążeniem |
|
# Bez SQM → RTT >15ms w spokojnej sieci, >100ms pod obciążeniem |
|
if [ "$DETECTED_RTT_MS" -le 5 ]; then |
|
SQM_ACTIVE=1 |
|
lok " SQM/CAKE wykryto aktywne (RTT ≤5ms) — tryb CAKE-aware" |
|
elif [ "$DETECTED_RTT_MS" -le 15 ]; then |
|
SQM_ACTIVE=1 |
|
lok " Prawdopodobnie SQM aktywne (RTT ≤15ms)" |
|
else |
|
SQM_ACTIVE=0 |
|
lwrn " SQM nieaktywne (RTT=${DETECTED_RTT_MS}ms) — bufferbloat ryzyko" |
|
fi |
|
fi |
|
fi |
|
|
|
# ── 0.4: Wi-Fi Band Detection ───────────────────────────────────────── |
|
# Wykryj czy urządzenie jest na 2.4GHz (degradowane) czy 5GHz (optymalne) |
|
WIFI_INFO=$(dumpsys wifi 2>/dev/null | grep -E 'freq|SSID|link' | head -5) |
|
WIFI_FREQ_MHZ=$(echo "$WIFI_INFO" | grep -oE 'freq=[0-9]+' | cut -d= -f2 | head -1) |
|
|
|
if [ -n "$WIFI_FREQ_MHZ" ]; then |
|
if [ "$WIFI_FREQ_MHZ" -ge 5000 ]; then |
|
WIFI_BAND="5GHz" |
|
lok " Wi-Fi: 5GHz (${WIFI_FREQ_MHZ}MHz) ✓" |
|
else |
|
WIFI_BAND="2.4GHz" |
|
lwrn " Wi-Fi: 2.4GHz (${WIFI_FREQ_MHZ}MHz) — DEGRADOWANE" |
|
lwrn " Ryzyko: bufferbloat + interferecje → janka 4K stream" |
|
fi |
|
fi |
|
|
|
lnfo "╚══ PROBE COMPLETE: ISP=$DETECTED_ISP MTU=$DETECTED_MTU RTT=${DETECTED_RTT_MS}ms SQM=$SQM_ACTIVE WIFI=$WIFI_BAND ══╝" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# MODULE 1: SQM-AWARE TCP STACK |
|
# |
|
# KRYTYCZNA ZMIANA v3.0: |
|
# Poprzednie wersje: rmem_max=8MB (wymiarowane dla RTT 40ms bez SQM) |
|
# v3.0: dynamiczne BDP-aware bufory na podstawie wykrytego RTT |
|
# |
|
# WZÓR BDP: BDP = Bandwidth × RTT / 8 |
|
# Bez SQM: 15Mbps × 0.040s / 8 = 75KB → 4x headroom = 300KB |
|
# Z CAKE: 15Mbps × 0.005s / 8 = 9.4KB → 4x headroom = 37.5KB |
|
# 4K peak: 25Mbps × 0.005s / 8 = 15.6KB → 4x headroom = 62.5KB |
|
# |
|
# Wartości wybrane z marginesem 8x BDP: |
|
# CAKE active: default=65536 (64KB), max=2097152 (2MB) |
|
# No SQM: default=262144 (256KB), max=8388608 (8MB) |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
mod_tcp_sqm_aware() { |
|
lnfo "╔══ MODULE 1: SQM-AWARE TCP STACK ══╗" |
|
lnfo " BDP calculation: RTT=${DETECTED_RTT_MS}ms, SQM=$SQM_ACTIVE" |
|
|
|
if [ "$SQM_ACTIVE" = "1" ]; then |
|
# ── CAKE-AWARE MODE ──────────────────────────────────────────────── |
|
# Z aktywnym CAKE na routerze duże bufory po stronie urządzenia |
|
# SZKODZĄ — powodują, że CAKE walczy z dużymi kolejkami TCP |
|
# Referencja: "large device buffers defeat purpose of CAKE" |
|
# Optymalne: małe bufory → szybkie RTT → BBR/CUBIC reaguje natychmiast |
|
lnfo " → Tryb CAKE-AWARE: małe bufory (anty-bufferbloat)" |
|
|
|
TCP_RMEM_DEF=65536 # 64KB — pokrywa BDP przy RTT 5ms, 100Mbps |
|
TCP_RMEM_MAX=2097152 # 2MB — burst headroom bez sabotowania CAKE |
|
TCP_WMEM_DEF=32768 # 32KB |
|
TCP_WMEM_MAX=2097152 # 2MB |
|
|
|
# KLUCZOWE: tcp_notsent_lowat przy SQM = niższy próg |
|
# Zapobiega wysyłaniu zbyt wielu danych naprzód (pacing helper) |
|
TCP_NOTSENT_LOWAT=32768 # 32KB z CAKE vs 131072 bez |
|
|
|
TCP_MODE_DESC="SQM/CAKE active" |
|
|
|
sw "/proc/sys/net/ipv4/tcp_notsent_lowat" "$TCP_NOTSENT_LOWAT" |
|
|
|
# tcp_rmem: min=4KB, default=64KB, max=2MB |
|
sw "/proc/sys/net/ipv4/tcp_rmem" \ |
|
"4096 $TCP_RMEM_DEF $TCP_RMEM_MAX" |
|
sw "/proc/sys/net/ipv4/tcp_wmem" \ |
|
"4096 $TCP_WMEM_DEF $TCP_WMEM_MAX" |
|
sw "/proc/sys/net/core/rmem_max" "$TCP_RMEM_MAX" |
|
sw "/proc/sys/net/core/wmem_max" "$TCP_WMEM_MAX" |
|
|
|
# Bufor Android dla Wi-Fi (dopasowany do CAKE BDP) |
|
ss global "net.tcp.buffersize.wifi" \ |
|
"4096,65536,2097152,32768,65536,2097152" |
|
sp "net.tcp.default_init_rwnd" "40" |
|
ss global "tcp_default_init_rwnd" "40" |
|
|
|
# Włącz ECN — kluczowe dla CAKE! CAKE używa ECN zamiast packet drop |
|
# Efekt: zero retransmisji przy CAKE + ECN = idealna AV sync |
|
sw "/proc/sys/net/ipv4/tcp_ecn" "1" |
|
sp "persist.net.tcp.ecn" "1" |
|
lok " ECN aktywne — CAKE+ECN = zero packet loss AQM ✓" |
|
|
|
else |
|
# ── STANDARD MODE (brak SQM) ────────────────────────────────────── |
|
# Bez CAKE na routerze: RTT może być wysoki → duże bufory pomagają |
|
# throughput (standard BDP sizing) |
|
lwrn " → Tryb STANDARD: duże bufory (SQM nieaktywne na routerze)" |
|
lwrn " ZALECENIE: włącz SQM CAKE na routerze dla eliminacji bufferbloat" |
|
|
|
TCP_RMEM_DEF=262144 # 256KB — standardowe BDP przy RTT 40ms |
|
TCP_RMEM_MAX=8388608 # 8MB — burst dla VP9 segment ~3MB |
|
TCP_WMEM_DEF=131072 # 128KB |
|
TCP_WMEM_MAX=8388608 # 8MB |
|
TCP_NOTSENT_LOWAT=131072 # 128KB — standardowe |
|
|
|
TCP_MODE_DESC="No SQM (legacy)" |
|
|
|
sw "/proc/sys/net/ipv4/tcp_notsent_lowat" "$TCP_NOTSENT_LOWAT" |
|
sw "/proc/sys/net/ipv4/tcp_rmem" \ |
|
"4096 $TCP_RMEM_DEF $TCP_RMEM_MAX" |
|
sw "/proc/sys/net/ipv4/tcp_wmem" \ |
|
"4096 $TCP_WMEM_DEF $TCP_WMEM_MAX" |
|
sw "/proc/sys/net/core/rmem_max" "$TCP_RMEM_MAX" |
|
sw "/proc/sys/net/core/wmem_max" "$TCP_WMEM_MAX" |
|
|
|
ss global "net.tcp.buffersize.wifi" \ |
|
"4096,262144,8388608,131072,262144,4194304" |
|
sp "net.tcp.default_init_rwnd" "120" |
|
ss global "tcp_default_init_rwnd" "120" |
|
|
|
# ECN wyłącz bez SQM — może powodować problemy z niektórymi routerami |
|
sw "/proc/sys/net/ipv4/tcp_ecn" "0" |
|
fi |
|
|
|
# ── Wspólne ustawienia TCP (niezależne od SQM) ───────────────────────── |
|
# CUBIC (kernel 4.9 BCM72604 — BBR niedostępny NA URZĄDZENIU) |
|
# UWAGA: router OpenWRT z kernel 6.x MOŻE mieć BBRv3 |
|
sw "/proc/sys/net/ipv4/tcp_congestion_control" "cubic" |
|
sw "/proc/sys/net/ipv4/tcp_fastopen" "3" |
|
sw "/proc/sys/net/ipv4/tcp_window_scaling" "1" |
|
sw "/proc/sys/net/ipv4/tcp_sack" "1" |
|
sw "/proc/sys/net/ipv4/tcp_no_metrics_save" "1" |
|
sw "/proc/sys/net/ipv4/tcp_slow_start_after_idle" "0" |
|
sw "/proc/sys/net/ipv4/tcp_syn_retries" "2" |
|
sw "/proc/sys/net/ipv4/tcp_fin_timeout" "15" |
|
sw "/proc/sys/net/ipv4/tcp_thin_linear_timeouts" "1" |
|
|
|
lok " TCP mode: $TCP_MODE_DESC | rmem_def=${TCP_RMEM_DEF}B max=${TCP_RMEM_MAX}B" |
|
lnfo "╚══ MODULE 1 DONE ══╝" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# MODULE 2: MTU OPTIMIZATION |
|
# |
|
# Dostosowuje MTU urządzenia do wykrytej ścieżki sieciowej: |
|
# - Orange PPPoE bez RFC4638: MTU=1452 (1492 - 40 TCP overhead) |
|
# - Orange PPPoE z RFC4638: MTU=1460 (1500 - 40 TCP overhead) |
|
# - T-Mobile DHCP / OpenWRT LAN: MTU=1460 |
|
# |
|
# Cel: eliminacja fragmentacji VP9/HEVC segmentów → brak resendów |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
mod_mtu_optimize() { |
|
lnfo "╔══ MODULE 2: MTU OPTIMIZATION ══╗" |
|
lnfo " Wykryte MTU ścieżki: $DETECTED_MTU | ISP: $DETECTED_ISP" |
|
|
|
# Oblicz optymalny TCP MSS = MTU - 20(IP) - 20(TCP) = MTU - 40 |
|
TCP_MSS=$((DETECTED_MTU - 40)) |
|
lnfo " Obliczony MSS: $TCP_MSS" |
|
|
|
# Ustaw MTU na interfejsach Wi-Fi |
|
for IFACE in wlan0 wlan1 swlan0; do |
|
if ip link show "$IFACE" >/dev/null 2>&1; then |
|
CURRENT_MTU=$(ip link show "$IFACE" 2>/dev/null | grep -oE 'mtu [0-9]+' | awk '{print $2}') |
|
if [ "$CURRENT_MTU" != "$DETECTED_MTU" ]; then |
|
ip link set dev "$IFACE" mtu "$DETECTED_MTU" 2>/dev/null && \ |
|
lfix " MTU $IFACE: $CURRENT_MTU → $DETECTED_MTU" || \ |
|
lwrn " Nie można ustawić MTU na $IFACE (brak root)" |
|
else |
|
lok " MTU $IFACE = $DETECTED_MTU (bez zmian)" |
|
fi |
|
fi |
|
done |
|
|
|
# Ustaw MTU dla Wi-Fi przez Android NetworkManager (API 28) |
|
sp "net.tcp.mtu.wlan0" "$DETECTED_MTU" |
|
|
|
# ISP-specyficzne DNS i captive portal |
|
case "$DETECTED_ISP" in |
|
ORANGE_*) |
|
lnfo " Konfiguracja dla Orange FTTH PPPoE..." |
|
# Orange używa własnych serwerów NTP — nadpisujemy Cloudflare |
|
ss global "ntp_server" "time.cloudflare.com" |
|
# Captive portal Orange |
|
ss global "captive_portal_http_url" \ |
|
"http://connectivitycheck.gstatic.com/generate_204" |
|
# MSS clamping hint (PPPoE powoduje MSS = 1452 dla MTU 1492) |
|
sp "net.tcp.mss.clamp" "$TCP_MSS" |
|
lok " Orange: MSS clamp=$TCP_MSS, NTP=Cloudflare" |
|
;; |
|
TMOBILE_*) |
|
lnfo " Konfiguracja dla T-Mobile DHCP..." |
|
ss global "ntp_server" "time.google.com" |
|
ss global "captive_portal_http_url" \ |
|
"http://connectivitycheck.gstatic.com/generate_204" |
|
lok " T-Mobile: MTU=1500 standardowe, NTP=Google" |
|
;; |
|
OPENWRT_CUSTOM) |
|
lnfo " OpenWRT detected: LAN MTU zgodne z WAN config routera" |
|
lok " Router zarządza MTU — urządzenie przyjmuje wartość routera" |
|
;; |
|
esac |
|
|
|
# Wi-Fi MTU clamp via Android prop |
|
sp "wifi.interface.mtu" "$DETECTED_MTU" |
|
|
|
lnfo "╚══ MODULE 2 DONE ══╝" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# MODULE 3: WI-FI 5GHz BAND STEERING |
|
# |
|
# Problem: BCM72604 może łączyć się z AP na 2.4GHz mimo dostępności 5GHz |
|
# Efekt: degradacja throughput, wysoki jitter, bufferbloat na warstwie 802.11 |
|
# Rozwiązanie: wymuszenie band preference 5GHz + RSSI threshold |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
mod_wifi_5ghz_steering() { |
|
lnfo "╔══ MODULE 3: WI-FI 5GHz BAND STEERING ══╗" |
|
lnfo " Aktualny band: ${WIFI_BAND:-nieznany} (${WIFI_FREQ_MHZ:-?}MHz)" |
|
|
|
# Wymuszenie preferencji 5GHz w Android Wi-Fi supplicant |
|
ss global "wifi_frequency_band" "1" # 1 = 5GHz preferred |
|
ss global "wifi_5ghz_preferred" "1" |
|
|
|
# Android Wi-Fi band selection props |
|
sp "wifi.interface.band.preference" "5" |
|
sp "persist.wifi.prefer5ghz" "1" |
|
|
|
# Wyłącz agresywne roaming triggery na 2.4GHz |
|
# (zapobiega reconnect do słabszego 2.4GHz AP podczas odtwarzania) |
|
ss global "wifi_rssi_to_5ghz_threshold" "-70" # dBm — minimalne RSSI 5GHz |
|
ss global "wifi_roaming_scan_frequency" "5" # s — rzadsze skanowanie |
|
|
|
# Optymalizacja skanowania (redukcja CPU spike podczas 4K playback) |
|
ss global "wifi_scan_throttle_enabled" "1" |
|
ss global "wifi_scan_always_enabled" "0" |
|
ss global "ble_scan_always_enabled" "0" |
|
sp "wifi.supplicant_scan_interval" "600" # 10 minut (vs 300s poprzednio) |
|
ss global "wifi_idle_ms" "600000" |
|
|
|
# Wyłącz Wi-Fi power save podczas odtwarzania (powoduje jitter 20-80ms) |
|
sp "wifi.ps.mode" "0" # 0 = no power save |
|
ss global "wifi_power_save" "0" |
|
|
|
# Android 9: Agresywne unikanie złej sieci (mogło powodować reconnect) |
|
ss global "network_avoid_bad_wifi" "0" |
|
|
|
if [ "$WIFI_BAND" = "2.4GHz" ]; then |
|
lwrn " UWAGA: Urządzenie nadal na 2.4GHz!" |
|
lwrn " → Sprawdź router: BSS Transition Management / 802.11v band steering" |
|
lwrn " → Upewnij się że AP 5GHz ma to samo SSID (unified SSID)" |
|
lwrn " → Na routerze OpenWRT: ubeacon (802.11k/v) wymaga hostapd 2.10+" |
|
else |
|
lok " Wi-Fi 5GHz aktywne — optymalny kanał dla 4K stream ✓" |
|
fi |
|
|
|
lnfo "╚══ MODULE 3 DONE ══╝" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# MODULE 4: IPTV MULTICAST COEXISTENCE |
|
# |
|
# Problem: z raportu OpenWRT — IGMP leave/join może być blokowany przez |
|
# Android firewall lub Wi-Fi driver BCM. |
|
# Objawy: obraz IPTV freezuje co 5-10s (router nie dostaje IGMP Join Reply) |
|
# |
|
# Rozwiązanie: upewnij się że urządzenie wysyła IGMP membership reports |
|
# i że Android nie throttluje pakietów multicast |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
mod_iptv_multicast_fix() { |
|
lnfo "╔══ MODULE 4: IPTV MULTICAST COEXISTENCE ══╗" |
|
|
|
# Upewnij się że multicast jest włączony na interfejsie Wi-Fi |
|
for IFACE in wlan0 wlan1; do |
|
if ip link show "$IFACE" >/dev/null 2>&1; then |
|
# Sprawdź czy MULTICAST flag jest ustawiony |
|
if ip link show "$IFACE" 2>/dev/null | grep -q MULTICAST; then |
|
lok " $IFACE: MULTICAST flag OK ✓" |
|
else |
|
ip link set "$IFACE" multicast on 2>/dev/null && \ |
|
lfix " $IFACE: włączono MULTICAST" || \ |
|
lwrn " $IFACE: nie można włączyć MULTICAST" |
|
fi |
|
fi |
|
done |
|
|
|
# IGMP version — igmpproxy na OpenWRT oczekuje IGMPv2/v3 |
|
sw "/proc/sys/net/ipv4/conf/wlan0/force_igmp_version" "2" |
|
sw "/proc/sys/net/ipv4/conf/default/force_igmp_version" "2" |
|
|
|
# Multicast TTL — pakiety IGMP muszą dotrzeć do routera (TTL=1 wystarczy) |
|
sw "/proc/sys/net/ipv4/conf/wlan0/mc_forwarding" "0" |
|
|
|
# Zmniejsz IGMP membership report interval |
|
# (szybsza reakcja na channel change w IPTV) |
|
sw "/proc/sys/net/ipv4/conf/all/arp_ignore" "0" |
|
sw "/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts" "0" |
|
|
|
# Android: nie blokuj multicast w sleep mode |
|
sp "persist.net.multicast.enabled" "true" |
|
|
|
# Sprawdź czy jest problem z DUP packets (Wi-Fi + Eth konflikt) |
|
# Na BCM72604: ro.nx.ethernet=0 → ethernet NIEAKTYWNY — ale warto potwierdzić |
|
ETH_STATE=$(ip link show eth0 2>/dev/null | grep 'state UP') |
|
WIFI_STATE=$(ip link show wlan0 2>/dev/null | grep 'state UP') |
|
|
|
if [ -n "$ETH_STATE" ] && [ -n "$WIFI_STATE" ]; then |
|
lwrn " KRYTYCZNE: Ethernet I Wi-Fi aktywne jednocześnie!" |
|
lwrn " → Przyczyna DUP packets i pętli sieciowych" |
|
lnfo " Dezaktywuję Ethernet (preferowane Wi-Fi na BCM72604)..." |
|
ip link set eth0 down 2>/dev/null && lok " eth0 DOWN — konflikt usunięty" |
|
ip neigh flush all 2>/dev/null |
|
lok " ARP cache wyczyszczony" |
|
else |
|
lok " Brak konfliktu Wi-Fi/Eth ✓" |
|
fi |
|
|
|
# Flush stale multicast routes |
|
ip mroute flush 2>/dev/null || true |
|
|
|
lnfo "╚══ MODULE 4 DONE ══╝" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# MODULE 5: SMART DNS — ISP-AWARE |
|
# |
|
# Na podstawie raportu OpenWRT: |
|
# - Orange PPPoE: własne DNS operatora często throttlują/cenzurują |
|
# - T-Mobile: DHCP DNS bywa wolny dla treści CDN |
|
# Rozwiązanie: DoT (DNS-over-TLS) z auto-testem latencji |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
mod_dns_smart() { |
|
lnfo "╔══ MODULE 5: SMART DNS (ISP-AWARE) ══╗" |
|
|
|
# Auto-test najszybszego DNS dla danego ISP |
|
# Metodologia: pomiar czasu odpowiedzi ICMP (proxy dla DoT RTT) |
|
BEST_DNS="" |
|
BEST_RTT=9999 |
|
|
|
for dns_host in "1.1.1.1" "8.8.8.8" "9.9.9.9" "94.140.14.14"; do |
|
rtt_raw=$(ping -c 4 -W 1 -i 0.1 "$dns_host" 2>/dev/null | \ |
|
grep -E 'rtt|round-trip' | sed 's/.*= //' | cut -d'/' -f2) |
|
rtt_int=$(echo "$rtt_raw" | awk -F. '{print $1}') |
|
if [ -n "$rtt_int" ] && [ "$rtt_int" -lt "$BEST_RTT" ]; then |
|
BEST_RTT=$rtt_int |
|
BEST_DNS=$dns_host |
|
fi |
|
lnfo " DNS $dns_host: ${rtt_int:-timeout}ms" |
|
done |
|
|
|
lnfo " → Najszybszy DNS: $BEST_DNS (${BEST_RTT}ms)" |
|
|
|
# Mapowanie IP → DoT hostname |
|
case "$BEST_DNS" in |
|
"1.1.1.1") DOT_HOST="one.one.one.one" ;; |
|
"8.8.8.8") DOT_HOST="dns.google" ;; |
|
"9.9.9.9") DOT_HOST="dns.quad9.net" ;; |
|
"94.140.14.14") DOT_HOST="dns.adguard.com" ;; |
|
*) DOT_HOST="one.one.one.one" ;; |
|
esac |
|
|
|
# Ustaw Private DNS (Android 9 / API 28) |
|
"$RISH_BIN" -c "settings put global private_dns_mode hostname" 2>/dev/null || \ |
|
ss global "private_dns_mode" "hostname" |
|
"$RISH_BIN" -c "settings put global private_dns_specifier $DOT_HOST" 2>/dev/null || \ |
|
ss global "private_dns_specifier" "$DOT_HOST" |
|
|
|
sp "net.dns1" "$BEST_DNS" |
|
sp "net.dns2" "8.8.8.8" |
|
|
|
# Captive portal — Google (neutralne dla wszystkich ISP) |
|
ss global "captive_portal_http_url" \ |
|
"http://connectivitycheck.gstatic.com/generate_204" |
|
ss global "captive_portal_https_url" \ |
|
"https://www.google.com/generate_204" |
|
ss global "captive_portal_mode" "0" |
|
|
|
lok " DNS-over-TLS: $DOT_HOST ($BEST_DNS, ${BEST_RTT}ms) ✓" |
|
lnfo "╚══ MODULE 5 DONE ══╝" |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# MODULE 6: ADAPTIVE GUARDIAN DAEMON v2.0 |
|
# |
|
# NOWE W v3.0: monitoruje stan sieci i reaguje na: |
|
# - Przełączenie band 2.4↔5GHz (wymusza powrót do 5GHz) |
|
# - Zmianę RTT (wykrywa włączenie/wyłączenie SQM) |
|
# - MTU mismatch (wykrywa reset MTU przez DHCP) |
|
# - DUP packets (natychmiastowy flush ARP) |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
guardian_daemon_v2() { |
|
# Uruchom: nohup sh $0 --daemon >/dev/null 2>&1 & |
|
_cycle=0 |
|
_last_band="${WIFI_BAND}" |
|
_last_sqm="${SQM_ACTIVE}" |
|
|
|
while true; do |
|
_cycle=$((_cycle+1)) |
|
|
|
# ── 1. Monitor Wi-Fi band ────────────────────────────────────────── |
|
_freq=$(dumpsys wifi 2>/dev/null | grep -oE 'freq=[0-9]+' | \ |
|
cut -d= -f2 | head -1) |
|
if [ -n "$_freq" ]; then |
|
if [ "$_freq" -lt 5000 ] && [ "$_last_band" = "5GHz" ]; then |
|
# Regresja do 2.4GHz — wymuś reconnect |
|
svc wifi disable 2>/dev/null |
|
sleep 2 |
|
svc wifi enable 2>/dev/null |
|
_last_band="2.4GHz" |
|
elif [ "$_freq" -ge 5000 ]; then |
|
_last_band="5GHz" |
|
fi |
|
fi |
|
|
|
# ── 2. Monitor RTT (SQM state change) ───────────────────────────── |
|
if [ $((_cycle % 20)) -eq 0 ] && [ -n "$GW_IP" ]; then |
|
_rtt=$(ping -c 5 -W 1 -i 0.1 "$GW_IP" 2>/dev/null | \ |
|
grep -E 'rtt|round-trip' | sed 's/.*= //' | \ |
|
cut -d'/' -f2 | awk -F. '{print $1}') |
|
if [ -n "$_rtt" ]; then |
|
if [ "$_rtt" -le 5 ] && [ "$_last_sqm" = "0" ]; then |
|
# SQM włączone przez router — dostosuj bufory |
|
_last_sqm=1 |
|
sw "/proc/sys/net/ipv4/tcp_rmem" "4096 65536 2097152" |
|
sw "/proc/sys/net/ipv4/tcp_notsent_lowat" "32768" |
|
sw "/proc/sys/net/ipv4/tcp_ecn" "1" |
|
elif [ "$_rtt" -gt 20 ] && [ "$_last_sqm" = "1" ]; then |
|
# SQM wyłączone — przywróć duże bufory |
|
_last_sqm=0 |
|
sw "/proc/sys/net/ipv4/tcp_rmem" "4096 262144 8388608" |
|
sw "/proc/sys/net/ipv4/tcp_notsent_lowat" "131072" |
|
sw "/proc/sys/net/ipv4/tcp_ecn" "0" |
|
fi |
|
fi |
|
fi |
|
|
|
# ── 3. DUP packet monitor ────────────────────────────────────────── |
|
if [ $((_cycle % 10)) -eq 0 ]; then |
|
_dup=$(ping -c 5 -W 1 1.1.1.1 2>/dev/null | grep -c 'DUP!') |
|
if [ "$_dup" -gt 0 ]; then |
|
# DUP wykryto — flush ARP i sprawdź Eth |
|
ip neigh flush all 2>/dev/null |
|
ETH_UP=$(ip link show eth0 2>/dev/null | grep 'state UP') |
|
[ -n "$ETH_UP" ] && ip link set eth0 down 2>/dev/null |
|
fi |
|
fi |
|
|
|
# ── 4. Standardowe moduły ochronne (z v2.0) ─────────────────────── |
|
# AV1 guard |
|
if [ $((_cycle % 15)) -eq 0 ]; then |
|
setprop media.codec.av1.disable true 2>/dev/null |
|
setprop debug.stagefright.c2.av1 0 2>/dev/null |
|
setprop audio.brcm.hdmi.clock_lock true 2>/dev/null |
|
fi |
|
|
|
# RAM guard |
|
_free_kb=$(awk '/MemFree/{print $2}' /proc/meminfo 2>/dev/null) |
|
if [ -n "$_free_kb" ] && [ "$_free_kb" -lt 153600 ]; then |
|
sync 2>/dev/null |
|
echo 1 > /proc/sys/vm/drop_caches 2>/dev/null |
|
fi |
|
|
|
sleep 45 |
|
done |
|
} |