46 lines
1.5 KiB
Go
46 lines
1.5 KiB
Go
// 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
|
|
}
|