mirror of https://github.com/ftl/tetra-pei
add commands to control the radio terminal
parent
a20458a904
commit
8d6b674382
@ -0,0 +1,68 @@
|
||||
package ctrl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ftl/tetra-pei/tetra"
|
||||
)
|
||||
|
||||
// SetOperatingMode according to [PEI] 6.14.7.2
|
||||
func SetOperatingMode(mode AIMode) string {
|
||||
return fmt.Sprintf("AT+CTOM=%d", mode)
|
||||
}
|
||||
|
||||
var requestOperatingModeResponse = regexp.MustCompile(`^\+CTOM: (\d+)$`)
|
||||
|
||||
// RequestOperatingMode reads the current operating mode according to [PEI] 6.14.7.4
|
||||
func RequestOperatingMode(ctx context.Context, requester tetra.Requester) (AIMode, error) {
|
||||
responses, err := requester.Request(ctx, "AT+CTOM?")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(responses) < 1 {
|
||||
return 0, fmt.Errorf("no response received")
|
||||
}
|
||||
response := strings.ToUpper(strings.TrimSpace(responses[0]))
|
||||
parts := requestOperatingModeResponse.FindStringSubmatch(response)
|
||||
|
||||
if len(parts) != 2 {
|
||||
return 0, fmt.Errorf("unexpected response: %s", responses[0])
|
||||
}
|
||||
|
||||
result, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return AIMode(result), nil
|
||||
}
|
||||
|
||||
// SetTalkgroup according to [PEI] 6.15.6.2
|
||||
func SetTalkgroup(gtsi string) string {
|
||||
return fmt.Sprintf("AT+CTGS=1,%s", gtsi)
|
||||
}
|
||||
|
||||
var requestTalkgroupResponse = regexp.MustCompile(`^\+CTGS: .*,(\d+)$`)
|
||||
|
||||
// RequestTalkgroup reads the current talkgroup according to [PEI] 6.15.6.4
|
||||
func RequestTalkgroup(ctx context.Context, requester tetra.Requester) (string, error) {
|
||||
responses, err := requester.Request(ctx, "AT+CTGS?")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(responses) < 1 {
|
||||
return "", fmt.Errorf("no response received")
|
||||
}
|
||||
response := strings.ToUpper(strings.TrimSpace(responses[0]))
|
||||
parts := requestTalkgroupResponse.FindStringSubmatch(response)
|
||||
|
||||
if len(parts) != 2 {
|
||||
return "", fmt.Errorf("unexpected response: %s", responses[0])
|
||||
}
|
||||
|
||||
return parts[1], nil
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package ctrl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// AIModeByName returns the AIMode with the given name
|
||||
func AIModeByName(name string) (AIMode, error) {
|
||||
sanitized := strings.ToUpper(strings.TrimSpace(name))
|
||||
result, ok := AIModesByName[sanitized]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("invalid operating mode %s", name)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// AIMode represents an operating mode according to [PEI] 6.17.4
|
||||
type AIMode byte
|
||||
|
||||
func (m AIMode) String() string {
|
||||
for k, v := range AIModesByName {
|
||||
if v == m {
|
||||
return k
|
||||
}
|
||||
}
|
||||
return "UNKNOWN"
|
||||
}
|
||||
|
||||
// All supported operating modes
|
||||
const (
|
||||
TMO AIMode = iota
|
||||
DMO
|
||||
)
|
||||
|
||||
// AIModesByName maps all supported operating modes by their string representation
|
||||
var AIModesByName = map[string]AIMode{
|
||||
"TMO": TMO,
|
||||
"DMO": DMO,
|
||||
}
|
Loading…
Reference in New Issue