diff options
Diffstat (limited to 'node_id.go')
| -rw-r--r-- | node_id.go | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/node_id.go b/node_id.go new file mode 100644 index 0000000..5e89145 --- /dev/null +++ b/node_id.go @@ -0,0 +1,77 @@ +package meshtastic + +import ( + "crypto/rand" + "encoding/binary" + "fmt" + "math" + "math/big" +) + +// NodeID holds the node identifier. This is a uint32 value which uniquely identifies a node within a mesh. +type NodeID uint32 + +const ( + // BroadcastNodeID is the special NodeID used when broadcasting a packet to a channel. + BroadcastNodeID NodeID = math.MaxUint32 + // ReservedNodeIDThreshold is the threshold at which NodeIDs are considered reserved. Random NodeIDs should not + // be generated below this threshold. + // Source: https://github.com/meshtastic/firmware/blob/d1ea58975755e146457a8345065e4ca357555275/src/mesh/NodeDB.cpp#L461 + reservedNodeIDThreshold NodeID = 4 +) + +// Uint32 returns the underlying uint32 value of the NodeID. +func (n NodeID) Uint32() uint32 { + return uint32(n) +} + +// String converts the NodeID to a hex formatted string. +// This is typically how NodeIDs are displayed in Meshtastic UIs. +func (n NodeID) String() string { + return fmt.Sprintf("!%08x", uint32(n)) +} + +// Bytes converts the NodeID to a byte slice +func (n NodeID) Bytes() []byte { + bytes := make([]byte, 4) // uint32 is 4 bytes + binary.BigEndian.PutUint32(bytes, n.Uint32()) + return bytes +} + +// DefaultLongName returns the default long node name based on the NodeID. +// Source: https://github.com/meshtastic/firmware/blob/d1ea58975755e146457a8345065e4ca357555275/src/mesh/NodeDB.cpp#L382 +func (n NodeID) DefaultLongName() string { + bytes := make([]byte, 4) // uint32 is 4 bytes + binary.BigEndian.PutUint32(bytes, n.Uint32()) + return fmt.Sprintf("Meshtastic %04x", bytes[2:]) +} + +// DefaultShortName returns the default short node name based on the NodeID. +// Last two bytes of the NodeID represented in hex. +// Source: https://github.com/meshtastic/firmware/blob/d1ea58975755e146457a8345065e4ca357555275/src/mesh/NodeDB.cpp#L382 +func (n NodeID) DefaultShortName() string { + bytes := make([]byte, 4) // uint32 is 4 bytes + binary.BigEndian.PutUint32(bytes, n.Uint32()) + return fmt.Sprintf("%04x", bytes[2:]) +} + +// RandomNodeID returns a randomised NodeID. +// It's recommended to call this the first time a node is started and persist the result. +// +// Hardware meshtastic nodes first try a NodeID of the last four bytes of the BLE MAC address. If that ID is already in +// use or invalid, a random NodeID is generated. +// Source: https://github.com/meshtastic/firmware/blob/d1ea58975755e146457a8345065e4ca357555275/src/mesh/NodeDB.cpp#L466 +func RandomNodeID() (NodeID, error) { + // Generates a random uint32 between reservedNodeIDThreshold and math.MaxUint32 + randomInt, err := rand.Int( + rand.Reader, + big.NewInt( + int64(math.MaxUint32-reservedNodeIDThreshold.Uint32()), + ), + ) + if err != nil { + return NodeID(0), fmt.Errorf("reading entropy: %w", err) + } + r := uint32(randomInt.Uint64()) + reservedNodeIDThreshold.Uint32() + return NodeID(r), nil +} |
