package main import ( "fmt" "google.golang.org/protobuf/proto" "powerpod/gotool/pb" ) func (m *managedSerial) getVersion() (*pb.VersionResponse, error) { payload, err := m.exchange(byte(pb.MessageType_VERSION), "VERSION") if err != nil { return nil, err } return decodeVersionPayload(payload) } func (m *managedSerial) getVersionPoll() (*pb.VersionResponse, error) { payload, err := m.exchangePoll(byte(pb.MessageType_VERSION), "VERSION") if err != nil { return nil, err } return decodeVersionPayload(payload) } func (m *managedSerial) listClients() ([]*pb.ClientInfo, error) { payload, err := m.exchange(byte(pb.MessageType_CLIENT_INFO), "CLIENT_INFO") if err != nil { return nil, err } return decodeClientsPayload(payload) } func (m *managedSerial) listClientsPoll() ([]*pb.ClientInfo, error) { payload, err := m.exchangePoll(byte(pb.MessageType_CLIENT_INFO), "CLIENT_INFO") if err != nil { return nil, err } return decodeClientsPayload(payload) } func (m *managedSerial) AccelDeadzone(req *pb.AccelDeadzoneRequest) (*pb.AccelDeadzoneResponse, error) { return m.accelDeadzoneVia(m.withPort, req) } func (m *managedSerial) AccelDeadzonePoll(req *pb.AccelDeadzoneRequest) (*pb.AccelDeadzoneResponse, error) { return m.accelDeadzoneVia(m.withPortPoll, req) } func (m *managedSerial) accelDeadzoneVia( portFn func(func(*serialPort) error) error, req *pb.AccelDeadzoneRequest, ) (*pb.AccelDeadzoneResponse, error) { var resp *pb.AccelDeadzoneResponse err := portFn(func(sp *serialPort) error { var e error resp, e = sp.AccelDeadzone(req) return e }) return resp, err } func (m *managedSerial) EspnowUnicastTest(clientID, seq uint32) (*pb.EspNowUnicastTestResponse, error) { var resp *pb.EspNowUnicastTestResponse err := m.withPort(func(sp *serialPort) error { var e error resp, e = sp.EspnowUnicastTest(clientID, seq) return e }) return resp, err } func decodeVersionPayload(payload []byte) (*pb.VersionResponse, error) { var msg pb.UartMessage if err := proto.Unmarshal(payload[1:], &msg); err != nil { return nil, fmt.Errorf("decode: %w", err) } if msg.GetType() != pb.MessageType_VERSION { return nil, fmt.Errorf("unexpected type %v", msg.GetType()) } ver := msg.GetVersionResponse() if ver == nil { return nil, fmt.Errorf("missing version_response") } return ver, nil } func decodeClientsPayload(payload []byte) ([]*pb.ClientInfo, error) { var msg pb.UartMessage if err := proto.Unmarshal(payload[1:], &msg); err != nil { return nil, fmt.Errorf("decode: %w", err) } if msg.GetType() != pb.MessageType_CLIENT_INFO { return nil, fmt.Errorf("unexpected type %v", msg.GetType()) } info := msg.GetClientInfoResponse() if info == nil { return nil, fmt.Errorf("missing client_info_response") } return info.GetClients(), nil } func (s *serialPort) getVersion() (*pb.VersionResponse, error) { payload, err := s.exchange(byte(pb.MessageType_VERSION), "VERSION") if err != nil { return nil, err } return decodeVersionPayload(payload) } func (s *serialPort) listClients() ([]*pb.ClientInfo, error) { payload, err := s.exchange(byte(pb.MessageType_CLIENT_INFO), "CLIENT_INFO") if err != nil { return nil, err } return decodeClientsPayload(payload) } func (s *serialPort) accelDeadzone(req *pb.AccelDeadzoneRequest) (*pb.AccelDeadzoneResponse, error) { msg := &pb.UartMessage{ Type: pb.MessageType_ACCEL_DEADZONE, Payload: &pb.UartMessage_AccelDeadzoneRequest{ AccelDeadzoneRequest: req, }, } body, err := proto.Marshal(msg) if err != nil { return nil, fmt.Errorf("encode: %w", err) } payload := append([]byte{byte(pb.MessageType_ACCEL_DEADZONE)}, body...) respPayload, err := s.exchangePayload(payload, "ACCEL_DEADZONE") if err != nil { return nil, err } var respMsg pb.UartMessage if err := proto.Unmarshal(respPayload[1:], &respMsg); err != nil { return nil, fmt.Errorf("decode: %w", err) } r := respMsg.GetAccelDeadzoneResponse() if r == nil { return nil, fmt.Errorf("missing accel_deadzone_response") } return r, nil } func (s *serialPort) espnowUnicastTest(clientID, seq uint32) (*pb.EspNowUnicastTestResponse, error) { req := &pb.EspNowUnicastTestRequest{ClientId: clientID, Seq: seq} msg := &pb.UartMessage{ Type: pb.MessageType_ESPNOW_UNICAST_TEST, Payload: &pb.UartMessage_EspnowUnicastTestRequest{ EspnowUnicastTestRequest: req, }, } body, err := proto.Marshal(msg) if err != nil { return nil, fmt.Errorf("encode: %w", err) } payload := append([]byte{byte(pb.MessageType_ESPNOW_UNICAST_TEST)}, body...) respPayload, err := s.exchangePayload(payload, "ESPNOW_UNICAST_TEST") if err != nil { return nil, err } var respMsg pb.UartMessage if err := proto.Unmarshal(respPayload[1:], &respMsg); err != nil { return nil, fmt.Errorf("decode: %w", err) } r := respMsg.GetEspnowUnicastTestResponse() if r == nil { return nil, fmt.Errorf("missing espnow_unicast_test_response") } return r, nil } func (s *serialPort) ledRingProgress(req *pb.LedRingProgressRequest) (*pb.LedRingProgressResponse, error) { msg := &pb.UartMessage{ Type: pb.MessageType_LED_RING, Payload: &pb.UartMessage_LedRingProgressRequest{ LedRingProgressRequest: req, }, } body, err := proto.Marshal(msg) if err != nil { return nil, fmt.Errorf("encode: %w", err) } payload := append([]byte{byte(pb.MessageType_LED_RING)}, body...) respPayload, err := s.exchangePayload(payload, "LED_RING") if err != nil { return nil, err } var respMsg pb.UartMessage if err := proto.Unmarshal(respPayload[1:], &respMsg); err != nil { return nil, fmt.Errorf("decode: %w", err) } r := respMsg.GetLedRingProgressResponse() if r == nil { return nil, fmt.Errorf("missing led_ring_progress_response") } return r, nil } func (s *serialPort) GetVersion() (*pb.VersionResponse, error) { return s.getVersion() } func (s *serialPort) ListClients() ([]*pb.ClientInfo, error) { return s.listClients() } func (s *serialPort) AccelDeadzone(req *pb.AccelDeadzoneRequest) (*pb.AccelDeadzoneResponse, error) { return s.accelDeadzone(req) } func (s *serialPort) EspnowUnicastTest(clientID, seq uint32) (*pb.EspNowUnicastTestResponse, error) { return s.espnowUnicastTest(clientID, seq) }