120 lines
3.2 KiB
Go
120 lines
3.2 KiB
Go
package uart
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"log"
|
|
"math"
|
|
|
|
"alox.tool/api"
|
|
)
|
|
|
|
func ParseFrameVersion(frame api.Frame) (api.PayloadVersion, error) {
|
|
if len(frame.Data) != api.PayloadVersionSize {
|
|
return api.PayloadVersion{}, fmt.Errorf("payload wrong size: got %d bytes, want 10", len(frame.Data))
|
|
}
|
|
|
|
v := api.PayloadVersion{
|
|
Version: binary.LittleEndian.Uint16(frame.Data[0:2]),
|
|
Buildhash: [7]uint8(frame.Data[2:10])}
|
|
return v, nil
|
|
}
|
|
|
|
func parseFrameClientInfoPart(data []byte) (api.PayloadClientInfo, error) {
|
|
if len(data) != api.PayloadClientInfoSize {
|
|
return api.PayloadClientInfo{}, fmt.Errorf("payload wrong size: got %d bytes, want 19", len(data))
|
|
}
|
|
|
|
v := api.PayloadClientInfo{
|
|
ClientID: data[0],
|
|
IsAvailable: data[1],
|
|
SlotIsUsed: data[2],
|
|
MACAddr: [6]uint8(data[3:9]),
|
|
LastPing: binary.LittleEndian.Uint32(data[9:13]),
|
|
LastSuccessfulPing: binary.LittleEndian.Uint32(data[13:17]),
|
|
Version: binary.LittleEndian.Uint16(data[17:19]),
|
|
}
|
|
|
|
return v, nil
|
|
}
|
|
|
|
func ParseFrameClientInfo(frame api.Frame) ([]api.PayloadClientInfo, error) {
|
|
if len(frame.Data) == 0 {
|
|
return nil, fmt.Errorf("empty frame data")
|
|
}
|
|
|
|
clientCount := int(frame.Data[0])
|
|
|
|
log.Printf("Clients %d", clientCount)
|
|
|
|
expectedLen := 1 + (clientCount * api.PayloadClientInfoSize)
|
|
|
|
if len(frame.Data) < expectedLen {
|
|
return nil, fmt.Errorf("frame data too short: got %d, want %d", len(frame.Data), expectedLen)
|
|
}
|
|
|
|
clientList := make([]api.PayloadClientInfo, 0, clientCount)
|
|
|
|
for i := 0; i < clientCount; i++ {
|
|
start := 1 + (i * api.PayloadClientInfoSize)
|
|
end := start + api.PayloadClientInfoSize
|
|
|
|
client, err := parseFrameClientInfoPart(frame.Data[start:end])
|
|
if err != nil {
|
|
log.Printf("Could not parse client part %d: %v", i, err)
|
|
continue
|
|
}
|
|
clientList = append(clientList, client)
|
|
}
|
|
|
|
return clientList, nil
|
|
}
|
|
|
|
func parseFrameClientInputPart(data []byte) (api.PayloadClientInput, error) {
|
|
if len(data) != api.PayloadClientInputSize {
|
|
return api.PayloadClientInput{}, fmt.Errorf("payload wrong size: got %d bytes, want 13", len(data))
|
|
}
|
|
|
|
v := api.PayloadClientInput{
|
|
ClientID: data[0],
|
|
X: math.Float32frombits(binary.LittleEndian.Uint32(data[1 : 1+4])),
|
|
Y: math.Float32frombits(binary.LittleEndian.Uint32(data[5 : 5+4])),
|
|
InputMask: binary.LittleEndian.Uint32(data[9 : 9+4]),
|
|
}
|
|
|
|
return v, nil
|
|
}
|
|
|
|
func ParseFrameClientInput(frame api.Frame) ([]api.PayloadClientInput, error) {
|
|
if len(frame.Data) == 0 {
|
|
return nil, fmt.Errorf("empty frame data")
|
|
}
|
|
|
|
clientCount := int(frame.Data[0])
|
|
|
|
log.Printf("Clients %d", clientCount)
|
|
|
|
expectedLen := 1 + (clientCount * api.PayloadClientInputSize)
|
|
|
|
if len(frame.Data) < expectedLen {
|
|
return nil, fmt.Errorf("frame data too short: got %d, want %d", len(frame.Data), expectedLen)
|
|
}
|
|
|
|
clientList := make([]api.PayloadClientInput, 0, clientCount)
|
|
|
|
for i := 0; i < clientCount; i++ {
|
|
start := 1 + (i * api.PayloadClientInputSize)
|
|
end := start + api.PayloadClientInputSize
|
|
|
|
client, err := parseFrameClientInputPart(frame.Data[start:end])
|
|
if err != nil {
|
|
log.Printf("Could not parse client art %d: %v", i, err)
|
|
continue
|
|
}
|
|
clientList = append(clientList, client)
|
|
}
|
|
|
|
return clientList, nil
|
|
|
|
}
|