Added draft SMS support.

This commit is contained in:
Andrey Egorov 2024-07-28 21:01:18 +03:00
parent 92d42d413a
commit ebab41c510
5 changed files with 138 additions and 3 deletions

View File

@ -15,3 +15,7 @@ func (resp Resp) RmFront(str string) Resp {
func (resp Resp) String() string {
return string(resp)
}
func (resp Resp) Bytes() []byte {
return []byte(resp)
}

View File

@ -37,6 +37,7 @@ func (gps *GpsData) calculateSpeed(newLatitude, newLongitude float64, lastUpdate
gps.Speed = earthRad * c / (math.Abs(float64(time.Since(lastUpdateTime))))
}
// Parse string from AT command that contains gps data
func (gps *GpsData) decode(str string) error {
var err error
newGpsInfo := GpsData{}

View File

@ -90,9 +90,9 @@ func (c *conn) checkReqs() error {
if err := c.ensurePackage("ppp"); err != nil {
return fmt.Errorf("ensure ppp package: %w", err)
}
if err := c.ensurePackage("net-tools"); err != nil {
return fmt.Errorf("ensure net-tools package: %w", err)
}
// if err := c.ensurePackage("net-tools"); err != nil {
// return fmt.Errorf("ensure net-tools package: %w", err)
// }
// Check SIM is valid
// AT+CPIN? and just check

69
api/modem/sms/errors.go Normal file
View File

@ -0,0 +1,69 @@
package sms
import (
"fmt"
"strconv"
)
func DecodeError(code int) string {
switch code {
case 300:
return "ME failure"
case 301:
return "SMS service of ME reserved"
case 302:
return "Operation not allowed"
case 303:
return "Operation not supported"
case 304:
return "Invalid PDU mode parameter"
case 305:
return "Invalid text mode parameter"
case 310:
return "SIM not inserted"
case 311:
return "SIM PIN required"
case 312:
return "PH-SIM PIN required"
case 313:
return "SIM failure"
case 314:
return "SIM busy"
case 315:
return "SIM wrong"
case 316:
return "SIM PUK required"
case 317:
return "SIM PIN2 required"
case 318:
return "SIM PUK2 required"
case 320:
return "Memory failure"
case 321:
return "Invalid memory index"
case 322:
return "Memory full"
case 330:
return "SMSC address unknown"
case 331:
return "No network service"
case 332:
return "Network timeout"
case 340:
return "NO +CNMA ACK EXPECTED"
case 341:
return "Buffer overflow"
case 342:
return "SMS size more than expected"
case 500:
return "Unknown error"
}
return "UNDEFINED ERROR CODE"
}
func GetError(msg []byte) (int, error) {
if len(msg) >= len("+CMS ERROR: ")+3 && string(msg[:len("+CMS ERROR: ")]) == "+CMS ERROR: " {
return strconv.Atoi(string(msg[len("+CMS ERROR: ") : len("+CMS ERROR: ")+3]))
}
return 0, fmt.Errorf("failed to parse error")
}

61
api/modem/sms/sms.go Normal file
View File

@ -0,0 +1,61 @@
package sms
import (
"fmt"
"io"
"log"
"strings"
"github.com/CGSG-2021-AE4/modem-test/api/modem/at"
)
type dialer struct {
logger *log.Logger
port at.Port
}
type Dialer interface {
Init() error
Send(number, msg string) error
ReadNew() ([]string, error)
io.Closer
}
func (d *dialer) Init() error {
// Ensure serial port
if !d.port.IsConnected() {
return fmt.Errorf("serial port is not connected")
}
// Ensure text format
if resp, err := d.port.Send("AT+CMGF=1"); err != nil || !resp.Check() {
if err != nil {
return fmt.Errorf("AT+CMGF=1 request: %w", err)
}
return fmt.Errorf("failed to set SMS format")
}
return nil
}
func (d *dialer) Send(number, msg string) error {
cmd := fmt.Sprintf("AT+CMGS=\"%s\"\r%s%c", number, msg, 26)
if resp, err := d.port.Send(cmd); err != nil || !resp.Check() {
if err != nil {
return fmt.Errorf("AT+CGMS= request: %w", err)
}
if errCode, err := GetError(resp.Bytes()); err != nil {
return fmt.Errorf("failed to send with SMS error: %s", DecodeError(errCode))
}
return fmt.Errorf("failed to send SMS")
}
return nil
}
// Reads all new messages
func (d *dialer) ReadNew() ([]string, error) {
resp, err := d.port.Send("AT+CMGL")
if err != nil {
return nil, fmt.Errorf("AT+CMGL request: %w", err)
}
msgs := strings.Split(strings.Replace(string(resp), "\r", "", -1), "\n")
return msgs, nil // TODO
}