sim-modem/api/modem/sms/sms.go

112 lines
2.5 KiB
Go
Raw Normal View History

2024-07-28 18:01:18 +00:00
package sms
import (
"fmt"
"io"
"log"
"strings"
2024-08-08 10:32:55 +00:00
"gitea.unprism.ru/KRBL/sim-modem/api/modem/at"
"gitea.unprism.ru/KRBL/sim-modem/api/modem/utils"
2024-07-28 18:01:18 +00:00
)
type dialer struct {
logger *log.Logger
port at.Port
}
2024-08-06 17:37:20 +00:00
type Sms interface {
2024-07-28 18:01:18 +00:00
Init() error
2024-08-06 17:37:20 +00:00
Send(number, msg string) error // Send sms
ReadNew() ([]string, error) // Read new smses
2024-07-28 18:01:18 +00:00
io.Closer
}
2024-08-06 17:37:20 +00:00
func New(logger *log.Logger, port at.Port) Sms {
2024-07-29 13:51:54 +00:00
return &dialer{
logger: logger,
port: port,
}
}
2024-07-28 18:01:18 +00:00
func (d *dialer) Init() error {
2024-08-09 15:17:20 +00:00
// Ensure serial port is connected
2024-07-28 18:01:18 +00:00
if !d.port.IsConnected() {
return fmt.Errorf("serial port is not connected")
}
2024-08-09 15:17:20 +00:00
// Check ping
if err := utils.CheckPIN(d.port, d.logger); err != nil {
2024-08-09 15:17:20 +00:00
return fmt.Errorf("check PIN: %w", err)
2024-08-06 18:10:24 +00:00
}
2024-08-09 15:17:20 +00:00
// Setup prefered message storage
// if err := d.setupMsgSt(); err != nil { // Does not use store now
// d.logger.Printf("ERROR setup msg storage: %s\n", err.Error())
// }
// Set notifications into console
if resp, err := d.port.Send("AT+CNMI=2,2"); err != nil || !resp.Check() {
if err != nil {
return err
}
return fmt.Errorf("CNMI= error response: %s", resp.String())
2024-08-09 15:17:20 +00:00
}
2024-08-09 15:17:20 +00:00
// Check number
if resp, err := d.port.Send("AT+CNUM"); err != nil || !resp.Check() {
2024-07-28 18:01:18 +00:00
if err != nil {
return err
2024-07-28 18:01:18 +00:00
}
return fmt.Errorf("CNUM error response: %s", resp.String())
2024-07-28 18:01:18 +00:00
}
return nil
}
func (d *dialer) Send(number, msg string) error {
2024-08-09 15:17:20 +00:00
sresp, err := d.port.Send(fmt.Sprintf(`AT+CMGSEX="%s"`, number)) // Because it will throw error
2024-07-29 15:53:55 +00:00
if err != nil {
2024-08-09 15:17:20 +00:00
return err
2024-07-28 18:01:18 +00:00
}
2024-08-09 15:17:20 +00:00
d.logger.Println(sresp)
// Message body
if err := d.port.RawSend(fmt.Sprintf("%s\x1A", msg)); err != nil {
2024-08-06 17:37:20 +00:00
return fmt.Errorf("message request: %w", err)
2024-07-29 15:53:55 +00:00
}
resp, err := d.port.RawRead(at.ReadTimeout)
if err != nil {
return fmt.Errorf("message request read: %w", err)
}
2024-08-09 15:17:20 +00:00
d.logger.Println("Send response:", resp)
if !at.Resp(resp).Check() {
return fmt.Errorf("error response: %s", resp)
2024-07-29 15:53:55 +00:00
}
2024-08-09 15:17:20 +00:00
return nil
2024-07-28 18:01:18 +00:00
}
// Reads all new messages
func (d *dialer) ReadNew() ([]string, error) {
2024-08-09 15:17:20 +00:00
resp, err := d.port.Send("AT+CMGL=\"ALL\"")
2024-07-28 18:01:18 +00:00
if err != nil {
2024-08-09 15:17:20 +00:00
return nil, err
2024-07-28 18:01:18 +00:00
}
2024-08-09 15:17:20 +00:00
d.logger.Println("raw sms:", resp)
2024-07-28 18:01:18 +00:00
msgs := strings.Split(strings.Replace(string(resp), "\r", "", -1), "\n")
2024-07-29 17:03:22 +00:00
outMsgs := make([]string, 0)
for _, s := range msgs {
if len(s) >= len("+CMGL:") && s[:len("+CMGL:")] == "+CMGL:" {
params := strings.Split(s[len("+CMGL:"):], ",")
d.logger.Println("GET MSG:", params)
} else {
outMsgs = append(outMsgs, s)
}
}
return outMsgs, nil // TODO
2024-07-28 18:01:18 +00:00
}
2024-07-29 13:51:54 +00:00
func (d *dialer) Close() error {
return nil
}