add a method to find out how many bits a message PDU may have

master
Florian Thienel 3 years ago
parent 3a558b1884
commit 76747bd18c

@ -1,7 +1,11 @@
package sds package sds
import ( import (
"context"
"fmt" "fmt"
"regexp"
"strconv"
"strings"
"github.com/ftl/tetra-pei/tetra" "github.com/ftl/tetra-pei/tetra"
) )
@ -16,17 +20,50 @@ func (f EncoderFunc) Encode() ([]byte, int) {
return f() return f()
} }
type RequesterFunc func(context.Context, string) ([]string, error)
const ( const (
// SwitchToSDSTL is a short-cut for selecting the SDS-TL AI service according to [PEI] 6.14.6 // 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" SwitchToSDSTL = "AT+CTSDS=12,0,0,0,1"
// SwitchToStatus is a short-cut for selecting the status AI service according to [PEI] 6.14.6 // 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" SwitchToStatus = "AT+CTSDS=13,0"
) )
// SendMessage according to [PEI] 6.13.2 // SendMessage according to [PEI] 6.13.2
func SendMessage(destination tetra.Identity, sds Encoder) string { func SendMessage(destination tetra.Identity, sds Encoder) string {
pdu := make([]byte, 0, 2000) // TODO use the maximum size allowed pdu := make([]byte, 0, 256)
pduBits := 0 pduBits := 0
pdu, pduBits = sds.Encode(pdu, pduBits) pdu, pduBits = sds.Encode(pdu, pduBits)
return fmt.Sprintf("AT+CMGS=%s,%d\x0d\x0a%s\x1a", destination, pduBits, tetra.BinaryToHex(pdu)) 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
} }

@ -1 +1,45 @@
package sds package sds
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
)
func TestRequestMaxPDUBits(t *testing.T) {
tt := []struct {
desc string
response []string
expected int
invalid bool
}{
{
desc: "empty",
invalid: true,
},
{
desc: "happy path",
response: []string{
"+CMGS: (0-16777214,00000001-10231638316777214,1-255,0-999999999999999999999999),(8-1184)",
"",
"OK",
},
expected: 1184,
},
}
for _, tc := range tt {
t.Run(tc.desc, func(t *testing.T) {
requester := func(_ context.Context, _ string) ([]string, error) {
return tc.response, nil
}
actual, err := RequestMaxMessagePDUBits(context.Background(), requester)
if tc.invalid {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expected, actual)
}
})
}
}

Loading…
Cancel
Save