// Package protocol содержит кодирование/декодирование команд устройства // (av/af/ar), вынесенное из internal/service, чтобы им мог пользоваться и // демон (через internal/service), и standalone-приложение (internal/localctl) // без зависимости друг от друга. package protocol import ( "fmt" "regexp" "strconv" ) var ( versionRe = regexp.MustCompile(`(?i)HW[:=]\s*([^\s]+).*?(?:FW|SW)[:=]\s*([^\s]+)`) freqRe = regexp.MustCompile(`(?i)\bf\d{7,9}\b`) ) // ParseVersion извлекает HW/FW из сырого ответа на команду "av". func ParseVersion(line string) (hw, sw string) { match := versionRe.FindStringSubmatch(line) if len(match) == 3 { return match[1], match[2] } return "", "" } // EncodeFrequencyCommand формирует команду "af" для частоты в МГц. func EncodeFrequencyCommand(frequency uint32) string { return fmt.Sprintf("af%07d", frequency*100) } // DecodeFrequencyResponse разбирает ответ на команду "ar" в частоту в МГц. func DecodeFrequencyResponse(line string) (uint32, error) { match := freqRe.FindString(line) if match == "" { return 0, fmt.Errorf("invalid frequency response %q", line) } value, err := strconv.ParseUint(match[1:], 10, 32) if err != nil { return 0, fmt.Errorf("invalid frequency response %q: %w", line, err) } return uint32(value / 100), nil }