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 }