mirror of
https://github.com/MeshCore-Beacon/beacon-server.git
synced 2026-09-01 16:48:19 +00:00
limited to repeaters and room servers stores high confidence matches from the nodes advert packet path first hops
93 lines
3.9 KiB
Go
93 lines
3.9 KiB
Go
package api
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/meshcore-go/meshcore-go"
|
|
)
|
|
|
|
// NodeNeighbor represents a neighboring node relationship observed in a given IATA.
|
|
type NodeNeighbor struct {
|
|
ID uuid.UUID `json:"id"`
|
|
Name *string `json:"name,omitempty"`
|
|
NodeType int16 `json:"nodeType"`
|
|
NodeTypeName string `json:"nodeTypeName"`
|
|
Latitude *float64 `json:"lat,omitempty"`
|
|
Longitude *float64 `json:"lng,omitempty"`
|
|
IATA string `json:"iata"`
|
|
ObservationCount int64 `json:"observationCount"`
|
|
FirstSeen int64 `json:"firstSeen"` // epoch ms
|
|
LastSeen int64 `json:"lastSeen"` // epoch ms
|
|
}
|
|
|
|
// NodeIATA represents a single IATA code and the last time the node was heard there.
|
|
type NodeIATA struct {
|
|
IATA string `json:"iata"`
|
|
LastHeard int64 `json:"lastHeard"` // epoch ms
|
|
}
|
|
|
|
// NodeSummary is the minimal node representation used in list responses.
|
|
type NodeSummary struct {
|
|
ID uuid.UUID `json:"id"`
|
|
PublicKey string `json:"publicKey"` // hex-encoded Ed25519 public key
|
|
NodeType int16 `json:"nodeType"` // 1=companion, 2=repeater, 3=room_server, 4=sensor
|
|
NodeTypeName string `json:"nodeTypeName"`
|
|
Name *string `json:"name,omitempty"`
|
|
IsObserver bool `json:"isObserver"` // true if this node is also a known observer
|
|
ObserverID *uuid.UUID `json:"observerId,omitempty"` // UUID of the associated observer row, if any
|
|
Latitude *float64 `json:"lat,omitempty"` // decimal degrees, from advert AppData
|
|
Longitude *float64 `json:"lng,omitempty"` // decimal degrees, from advert AppData
|
|
Radio *string `json:"radio,omitempty"` // shorthand: "freqMhz,bwKhz,sf" e.g. "910.5,62.5,7"
|
|
IATAs []NodeIATA `json:"iatas"` // IATAs where this node has been heard, with last heard timestamps
|
|
DefaultScope *string `json:"defaultScope,omitempty"` // most recently matched transport scope name e.g. "#bc"
|
|
}
|
|
|
|
// Node is the full node representation including firmware capability flags,
|
|
// location source, and timing metadata.
|
|
type Node struct {
|
|
NodeSummary
|
|
LocationSource *string `json:"locationSource,omitempty"` // "advert" or "manual"
|
|
LastAdvertAt *int64 `json:"lastAdvertAt,omitempty"` // epoch ms, nil if no advert received
|
|
SupportsMultibytePaths bool `json:"supportsMultibytePaths"` // firmware >= 1.14.0; detected via path hash size
|
|
SupportsMultibyteTraces bool `json:"supportsMultibyteTraces"` // firmware >= 1.11.0; detected via trace hash size
|
|
MinFirmwareVersion *string `json:"minFirmwareVersion,omitempty"` // derived from capability flags
|
|
FirstSeen int64 `json:"firstSeen"` // epoch ms
|
|
LastSeen int64 `json:"lastSeen"` // epoch ms
|
|
Metadata any `json:"metadata,omitempty"` // raw JSONB metadata
|
|
Neighbors []NodeNeighbor `json:"neighbors"`
|
|
}
|
|
|
|
// NodeTypeName returns a human-readable name for a node type integer.
|
|
func NodeTypeName(t int16) string {
|
|
switch byte(t) {
|
|
case meshcore.AdvertTypeChat:
|
|
return "companion"
|
|
case meshcore.AdvertTypeRepeater:
|
|
return "repeater"
|
|
case meshcore.AdvertTypeRoom:
|
|
return "room_server"
|
|
case meshcore.AdvertTypeSensor:
|
|
return "sensor"
|
|
default:
|
|
return "unknown"
|
|
}
|
|
}
|
|
|
|
// NodeTypeFromString returns the integer node type for a given name.
|
|
// Returns 0 (no filter) if the string is empty or unrecognized.
|
|
func NodeTypeFromString(s string) int16 {
|
|
switch strings.ToLower(s) {
|
|
case "companion", "chat":
|
|
return int16(meshcore.AdvertTypeChat)
|
|
case "repeater":
|
|
return int16(meshcore.AdvertTypeRepeater)
|
|
case "room_server", "roomserver", "room-server", "room":
|
|
return int16(meshcore.AdvertTypeRoom)
|
|
case "sensor":
|
|
return int16(meshcore.AdvertTypeSensor)
|
|
default:
|
|
return 0
|
|
}
|
|
}
|