Expose best_effort/fast/wait/reliable via UART, dashboard, and CLI so loss vs latency can be compared under real multi-pod load. Co-authored-by: Cursor <cursoragent@cursor.com>
101 lines
2.8 KiB
Go
101 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
pb "powerpod/gotool/pb"
|
|
)
|
|
|
|
type inputSendModeAPIResponse struct {
|
|
Success bool `json:"success"`
|
|
Mode uint32 `json:"mode"`
|
|
ModeName string `json:"mode_name"`
|
|
ClientID uint32 `json:"client_id,omitempty"`
|
|
SlavesUpdated uint32 `json:"slaves_updated,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
func inputSendModeName(mode pb.InputSendMode) string {
|
|
switch mode {
|
|
case pb.InputSendMode_INPUT_SEND_BEST_EFFORT:
|
|
return "best_effort"
|
|
case pb.InputSendMode_INPUT_SEND_FAST:
|
|
return "fast"
|
|
case pb.InputSendMode_INPUT_SEND_WAIT:
|
|
return "wait"
|
|
case pb.InputSendMode_INPUT_SEND_RELIABLE:
|
|
return "reliable"
|
|
default:
|
|
return "unknown"
|
|
}
|
|
}
|
|
|
|
func mountInputSendModeAPI(mux *http.ServeMux, link *managedSerial) {
|
|
mux.HandleFunc("/api/input-send-mode", func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
serveInputSendModeGet(w, link)
|
|
case http.MethodPut, http.MethodPost:
|
|
serveInputSendModePut(w, r, link)
|
|
default:
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
}
|
|
})
|
|
}
|
|
|
|
func serveInputSendModeGet(w http.ResponseWriter, link *managedSerial) {
|
|
resp, err := link.InputSendMode(&pb.InputSendModeRequest{Write: false})
|
|
if err != nil {
|
|
writeJSON(w, http.StatusBadGateway, inputSendModeAPIResponse{Error: err.Error()})
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, inputSendModeAPIResponse{
|
|
Success: resp.GetSuccess(),
|
|
Mode: uint32(resp.GetMode()),
|
|
ModeName: inputSendModeName(resp.GetMode()),
|
|
})
|
|
}
|
|
|
|
func serveInputSendModePut(w http.ResponseWriter, r *http.Request, link *managedSerial) {
|
|
var body struct {
|
|
Mode uint32 `json:"mode"`
|
|
ClientID uint32 `json:"client_id"`
|
|
AllClients bool `json:"all_clients"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
|
writeJSON(w, http.StatusBadRequest, inputSendModeAPIResponse{Error: "invalid JSON"})
|
|
return
|
|
}
|
|
if body.Mode > uint32(pb.InputSendMode_INPUT_SEND_RELIABLE) {
|
|
writeJSON(w, http.StatusBadRequest, inputSendModeAPIResponse{Error: "mode must be 0..3"})
|
|
return
|
|
}
|
|
if !body.AllClients && body.ClientID == 0 {
|
|
// Dashboard default: apply to every registered slave.
|
|
body.AllClients = true
|
|
}
|
|
|
|
resp, err := link.InputSendMode(&pb.InputSendModeRequest{
|
|
Write: true,
|
|
Mode: pb.InputSendMode(body.Mode),
|
|
ClientId: body.ClientID,
|
|
AllClients: body.AllClients,
|
|
})
|
|
if err != nil {
|
|
writeJSON(w, http.StatusBadGateway, inputSendModeAPIResponse{Error: err.Error()})
|
|
return
|
|
}
|
|
status := http.StatusOK
|
|
if !resp.GetSuccess() {
|
|
status = http.StatusBadRequest
|
|
}
|
|
writeJSON(w, status, inputSendModeAPIResponse{
|
|
Success: resp.GetSuccess(),
|
|
Mode: uint32(resp.GetMode()),
|
|
ModeName: inputSendModeName(resp.GetMode()),
|
|
ClientID: resp.GetClientId(),
|
|
SlavesUpdated: resp.GetSlavesUpdated(),
|
|
})
|
|
}
|