You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tetra-pei/sds/command.go

70 lines
1.8 KiB
Go

package sds
import (
"context"
"fmt"
"regexp"
"strconv"
"strings"
"github.com/ftl/tetra-pei/tetra"
)
type Encoder interface {
Encode([]byte, int) ([]byte, int)
}
type EncoderFunc func() ([]byte, int)
func (f EncoderFunc) Encode() ([]byte, int) {
return f()
}
type RequesterFunc func(context.Context, string) ([]string, error)
const (
// CRLF line ending for AT commands
CRLF = "\x0d\x0a"
// CtrlZ line ending for PDUs
CtrlZ = "\x1a"
// SwitchToSDSTL is a short-cut for selecting the SDS-TL AI service with ISSI addressing and E2EE according to [PEI] 6.14.6
SwitchToSDSTL = "AT+CTSDS=12,0,0,0,1"
// SwitchToStatus is a short-cut for selecting the status AI service with ISSI addresssing according to [PEI] 6.14.6
SwitchToStatus = "AT+CTSDS=13,0"
)
// SendMessage according to [PEI] 6.13.2
func SendMessage(destination tetra.Identity, sds Encoder) string {
pdu := make([]byte, 0, 256)
pduBits := 0
pdu, pduBits = sds.Encode(pdu, pduBits)
return fmt.Sprintf("AT+CMGS=%s,%d"+CRLF+"%s"+CtrlZ, destination, pduBits, tetra.BinaryToHex(pdu))
}
var sendMessageDescription = regexp.MustCompile(`^\+CMGS: .+\(\d*-(\d*)\)$`)
// RequestMaxMessagePDUBits uses the given RequesterFunc to find out how many bits a message PDU may have (see [PEI] 6.13.2).
func RequestMaxMessagePDUBits(ctx context.Context, requester RequesterFunc) (int, error) {
responses, err := requester(ctx, "AT+CMGS=?")
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 := sendMessageDescription.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 result, nil
}