package sms import ( "fmt" "io" "log" "strings" "time" "gitea.unprism.ru/KRBL/sim-modem/api/modem/at" "gitea.unprism.ru/KRBL/sim-modem/api/modem/utils" ) type dialer struct { logger *log.Logger port at.Port } type Sms interface { Init() error Send(number, msg string) error // Send sms ReadNew() ([]string, error) // Read new smses io.Closer } func New(logger *log.Logger, port at.Port) Sms { return &dialer{ logger: logger, port: port, } } func (d *dialer) Init() error { // Ensure serial port is connected if !d.port.IsConnected() { return fmt.Errorf("serial port is not connected") } // Check ping if err := utils.CheckPIN(d.port, d.logger); err != nil { return fmt.Errorf("check PIN: %w", err) } // Setup prefered message storage if err := d.setupMsgSt(); err != nil { d.logger.Printf("ERROR setup msg storage: %s\n", err.Error()) } // Check number if resp, err := d.port.Send("AT+CNUM"); err != nil || !resp.Check() { if err != nil { return fmt.Errorf("AT+CNUM request ") } } return nil } func (d *dialer) Send(number, msg string) error { sresp, err := d.port.Send(fmt.Sprintf(`AT+CMGSEX="%s"`, number)) // Because it will throw error if err != nil { return err } d.logger.Println(sresp) resp, err := d.port.RawSend(fmt.Sprintf("%s\x1A", msg), time.Millisecond) // Add additional \r\n because there is not supposed to be if err != nil { return fmt.Errorf("message request: %w", err) } d.logger.Println("Send response:", resp) if !at.Resp(resp).Check() { return fmt.Errorf("error response: %s", resp) } return nil } // Reads all new messages func (d *dialer) ReadNew() ([]string, error) { resp, err := d.port.Send("AT+CMGL=\"ALL\"") if err != nil { return nil, err } d.logger.Println("raw sms:", resp) msgs := strings.Split(strings.Replace(string(resp), "\r", "", -1), "\n") 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 } func (d *dialer) Close() error { return nil }