Reticulum-Go/pkg/interfaces/modem73_control.go
Ivan 5818dc8ba5
refactor: clear revive naming and control-flow warnings
Rename builtin shadows and case-colliding helpers, and tidy return/context/empty-block rules so lint is only add-constant noise.
2026-08-13 10:10:04 -05:00

89 lines
2.4 KiB
Go

// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024-2026 Quad4.io
package interfaces
import (
"encoding/binary"
"encoding/json"
"fmt"
"io"
)
const (
modem73MaxControlJSON = 1 << 20
modem73ControlHdrLen = 4
)
// Modem73WriteControl sends one length-prefixed JSON control message.
func Modem73WriteControl(w io.Writer, msg any) error {
return writeModem73Control(w, msg)
}
// Modem73ReadControl reads one length-prefixed JSON control object.
func Modem73ReadControl(r io.Reader) (map[string]any, error) {
return readModem73Control(r)
}
// modem73EncodeControl writes a length-prefixed JSON control message.
func modem73EncodeControl(msg any) ([]byte, error) {
body, err := json.Marshal(msg)
if err != nil {
return nil, err
}
if len(body) > modem73MaxControlJSON {
return nil, fmt.Errorf("modem73 control message too large: %d", len(body))
}
out := make([]byte, modem73ControlHdrLen+len(body))
binary.BigEndian.PutUint32(out[:modem73ControlHdrLen], uint32(len(body))) // #nosec G115 -- body capped at modem73MaxControlJSON
copy(out[modem73ControlHdrLen:], body)
return out, nil
}
// writeModem73Control sends one control message on w.
func writeModem73Control(w io.Writer, msg any) error {
frame, err := modem73EncodeControl(msg)
if err != nil {
return err
}
_, err = w.Write(frame)
return err
}
// readModem73Control reads one length-prefixed JSON object from r.
func readModem73Control(r io.Reader) (map[string]any, error) {
var hdr [modem73ControlHdrLen]byte
if _, err := io.ReadFull(r, hdr[:]); err != nil {
return nil, err
}
n := binary.BigEndian.Uint32(hdr[:])
if n > modem73MaxControlJSON {
return nil, fmt.Errorf("modem73 control length %d exceeds cap %d", n, modem73MaxControlJSON)
}
if n == 0 {
return map[string]any{}, nil
}
body := make([]byte, n)
if _, err := io.ReadFull(r, body); err != nil {
return nil, err
}
var msg map[string]any
if err := json.Unmarshal(body, &msg); err != nil {
return nil, err
}
return msg, nil
}
// modem73ComputeMTU derives hardware MTU from modem payload size.
func modem73ComputeMTU(payloadSize, overhead, floor int) int {
raw := payloadSize - overhead
if raw < floor {
return floor
}
return raw
}
// modem73NeedsFragmentation reports whether payloadSize cannot carry floor MTU.
func modem73NeedsFragmentation(payloadSize, overhead, floor int) bool {
return (payloadSize - overhead) < floor
}