Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/node_modules
2 changes: 1 addition & 1 deletion app/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1400,7 +1400,7 @@
"currentChannel": "Current channel",
"recommendedChannel": "Recommended channel",
"neighbors": "Neighbor APs",
"noScans": "No recent scans. Enable the agent on a router to collect neighbors.",
"noScans": "No recent scans for this router. Routers running NetGrip (gateway, APs managed by its panel) do not scan neighbors; routers with the NetPulse agent do. Pick another router from the list (e.g. rt2 or rt4) to see its plan.",
"noRadios": "This router does not report WiFi radios.",
"apply": "Apply channel",
"gateway": " (Gateway)",
Expand Down
2 changes: 1 addition & 1 deletion app/public/locales/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1400,7 +1400,7 @@
"currentChannel": "Canal actual",
"recommendedChannel": "Canal recomendado",
"neighbors": "APs vecinos",
"noScans": "No hay scans recientes. Activa el agente en un router para recoger vecinos.",
"noScans": "Sin escaneos recientes para este router. Los routers que corren NetGrip (gateway, APs gestionados por su panel) no escanean vecinos; los que llevan el agente NetPulse sí. Selecciona otro router de la lista (p. ej. rt2 o rt4) para ver su plan.",
"noRadios": "Este dispositivo no reporta radios WiFi.",
"apply": "Aplicar canal",
"gateway": " (Puerta de enlace)",
Expand Down
7 changes: 7 additions & 0 deletions server-go/internal/channelplan/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ func (s *Store) Recommend(routerID string, radios []probe.Radio, within time.Dur
bestCh = ch
}
}
// #518: el canal ACTUAL puede ser DFS (52/100/112/116...) y no estar en
// candidateChannels (solo no-DFS para recomendar). Su score es
// informativo ("cuánto ruido tengo ahora") y debe calcularse igual,
// no quedarse en MaxInt y pintar 9223372036854775807 en la UI.
if currentScore == math.MaxInt {
currentScore = channelScore(byBand[band], r.Channel)
}
if bestCh != 0 && bestScore != math.MaxInt {
rec.Recommended = bestCh
rec.CurrentScore = currentScore
Expand Down
41 changes: 41 additions & 0 deletions server-go/internal/channelplan/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,44 @@ func TestRecommendPasaSeccion(t *testing.T) {
t.Errorf("sin sección el iface debe caer al placeholder: %+v", *nosec)
}
}

func TestRecommendCurrentDfsChannelScoreNotMaxInt(t *testing.T) {
// #518: si el canal ACTUAL es DFS (112) y no está en candidateChannels
// (solo no-DFS), su score debe calcularse igual (es informativo) y no
// quedarse en MaxInt (la UI pintaba 9223372036854775807).
d, err := db.Open(t.TempDir())
if err != nil {
t.Fatalf("db: %v", err)
}
defer d.Close()

st := channelplan.NewStore(d.DB)
now := time.Now().Unix()
scans := []probe.ScanResult{
{Iface: "wlan1", BSSID: "aa:bb:cc:dd:ee:01", SSID: "V", Channel: 112, Freq: 5560, Signal: -60},
{Iface: "wlan1", BSSID: "aa:bb:cc:dd:ee:02", SSID: "W", Channel: 44, Freq: 5220, Signal: -55},
{Iface: "wlan1", BSSID: "aa:bb:cc:dd:ee:03", SSID: "X", Channel: 116, Freq: 5580, Signal: -70},
}
if err := st.SaveScan("rt1", now, scans); err != nil {
t.Fatalf("save: %v", err)
}

radios := []probe.Radio{{Name: "5 GHz", Channel: 112, WidthMhz: 80}}
recs, err := st.Recommend("rt1", radios, time.Hour)
if err != nil {
t.Fatalf("recommend: %v", err)
}
if len(recs) != 1 {
t.Fatalf("esperaba 1 radio, got %d", len(recs))
}
rec := recs[0]
if rec.CurrentScore > 1_000_000_000_000 {
t.Fatalf("currentScore no debe ser MaxInt (canal DFS): %d", rec.CurrentScore)
}
if rec.Recommended == 112 {
t.Errorf("no debería recomendar el DFS 112 ocupado: %+v", rec)
}
if rec.Recommended != 36 {
t.Errorf("debería recomendar el 36 libre (no-DFS), got %d", rec.Recommended)
}
}
Loading