used fixed-sized array for streamname instead of slice.

factory method now validates streamname size.

framecounter now stored as uint32. it's written to a byte buffer on each call to {Packet}.header()
add comment regarding framecounter wraparound.
This commit is contained in:
onyx-and-iris 2026-02-14 20:40:38 +00:00
parent ecd16545ab
commit 0d0dbedbcd

View File

@ -3,6 +3,7 @@ package vbantxt
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt"
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
) )
@ -21,25 +22,39 @@ var BpsOpts = []int{
} }
type packet struct { type packet struct {
streamname []byte streamname [streamNameSz]byte
bpsIndex int bpsIndex uint8
channel int channel uint8
framecounter []byte framecounter uint32
hbuf *bytes.Buffer hbuf *bytes.Buffer
} }
// newPacket returns a packet struct with default values, framecounter at 0. // newPacket creates a new packet with the given stream name and default values for other fields.
func newPacket(streamname string) packet { // It validates the stream name length and ensures the default baud rate is present in BpsOpts.
streamnameBuf := make([]byte, streamNameSz) func newPacket(streamname string) (packet, error) {
copy(streamnameBuf, streamname) if len(streamname) > streamNameSz {
return packet{}, fmt.Errorf(
"streamname too long: %d chars, max %d",
len(streamname),
streamNameSz,
)
}
var streamnameBuf [streamNameSz]byte
copy(streamnameBuf[:], streamname)
bpsIndex := indexOf(BpsOpts, 256000)
if bpsIndex == -1 {
return packet{}, fmt.Errorf("default baud rate 256000 not found in BpsOpts")
}
return packet{ return packet{
streamname: streamnameBuf, streamname: streamnameBuf,
bpsIndex: 0, bpsIndex: uint8(bpsIndex),
channel: 0, channel: 0,
framecounter: make([]byte, 4), framecounter: 0,
hbuf: bytes.NewBuffer(make([]byte, headerSz)), hbuf: bytes.NewBuffer(make([]byte, 0, headerSz)),
} }, nil
} }
// sr defines the samplerate for the request. // sr defines the samplerate for the request.
@ -60,15 +75,20 @@ func (p *packet) header() []byte {
p.hbuf.WriteByte(byte(0)) p.hbuf.WriteByte(byte(0))
p.hbuf.WriteByte(p.nbc()) p.hbuf.WriteByte(p.nbc())
p.hbuf.WriteByte(byte(0x10)) p.hbuf.WriteByte(byte(0x10))
p.hbuf.Write(p.streamname) p.hbuf.Write(p.streamname[:])
p.hbuf.Write(p.framecounter)
var frameBytes [4]byte
binary.LittleEndian.PutUint32(frameBytes[:], p.framecounter)
p.hbuf.Write(frameBytes[:])
return p.hbuf.Bytes() return p.hbuf.Bytes()
} }
// bumpFrameCounter increments the frame counter by 1. // bumpFrameCounter increments the frame counter by 1.
// The uint32 will safely wrap to 0 after reaching max value (4,294,967,295),
// which is expected behaviour for network protocol sequence numbers.
func (p *packet) bumpFrameCounter() { func (p *packet) bumpFrameCounter() {
x := binary.LittleEndian.Uint32(p.framecounter) p.framecounter++
binary.LittleEndian.PutUint32(p.framecounter, x+1)
log.Debugf("framecounter: %d", x) log.Debugf("framecounter: %d", p.framecounter)
} }