2024-07-18 16:34:26 +00:00
|
|
|
package modem
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2024-07-25 13:58:09 +00:00
|
|
|
"io"
|
2024-07-18 16:34:26 +00:00
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"strings"
|
2024-08-06 18:10:24 +00:00
|
|
|
"sync"
|
2024-07-18 16:34:26 +00:00
|
|
|
"time"
|
2024-07-22 15:53:34 +00:00
|
|
|
|
2024-08-08 10:26:33 +00:00
|
|
|
"gitea.unprism.ru/KRBL/sim-modem/api/modem/at"
|
|
|
|
"gitea.unprism.ru/KRBL/sim-modem/api/modem/gpio"
|
|
|
|
"gitea.unprism.ru/KRBL/sim-modem/api/modem/gps"
|
|
|
|
"gitea.unprism.ru/KRBL/sim-modem/api/modem/internet"
|
|
|
|
"gitea.unprism.ru/KRBL/sim-modem/api/modem/sms"
|
2024-07-18 16:34:26 +00:00
|
|
|
)
|
|
|
|
|
2024-07-25 13:58:09 +00:00
|
|
|
type ModemData struct {
|
|
|
|
Port string `json:"Port"`
|
2024-07-31 11:51:29 +00:00
|
|
|
gps.Data
|
2024-07-25 13:58:09 +00:00
|
|
|
}
|
|
|
|
|
2024-07-18 16:34:26 +00:00
|
|
|
type modem struct {
|
2024-07-23 14:59:26 +00:00
|
|
|
// Internal values
|
|
|
|
logger *log.Logger
|
2024-08-06 18:10:24 +00:00
|
|
|
mutex sync.Mutex
|
2024-07-23 14:59:26 +00:00
|
|
|
|
|
|
|
// Serial values
|
2024-08-06 17:37:20 +00:00
|
|
|
baudrate int
|
2024-07-23 16:02:28 +00:00
|
|
|
deviceName string
|
|
|
|
port at.Port
|
2024-07-18 16:34:26 +00:00
|
|
|
|
2024-07-23 14:59:26 +00:00
|
|
|
// Gpio values
|
2024-08-06 17:37:20 +00:00
|
|
|
onOffPin gpio.Pin // For turning on and off
|
2024-07-18 16:34:26 +00:00
|
|
|
|
|
|
|
// Other values
|
|
|
|
lastUpdateTime time.Time
|
2024-07-27 13:01:27 +00:00
|
|
|
|
|
|
|
// GPS
|
2024-07-31 11:51:29 +00:00
|
|
|
gps gps.Gps
|
2024-07-27 13:01:27 +00:00
|
|
|
|
|
|
|
// Internet connection
|
|
|
|
ic internet.Conn
|
2024-07-29 13:51:54 +00:00
|
|
|
|
|
|
|
// Sms and calls
|
2024-08-06 17:37:20 +00:00
|
|
|
sms sms.Sms
|
2024-07-18 16:34:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Modem interface {
|
|
|
|
Init() error
|
2024-08-06 17:37:20 +00:00
|
|
|
IsConnected() bool
|
2024-07-18 16:34:26 +00:00
|
|
|
Update() error
|
2024-07-31 11:51:29 +00:00
|
|
|
GetData() ModemData
|
2024-07-29 13:51:54 +00:00
|
|
|
|
2024-08-07 14:34:56 +00:00
|
|
|
PowerOn() error
|
|
|
|
PowerOff() error
|
|
|
|
|
2024-08-06 17:37:20 +00:00
|
|
|
// Access to SMS, GPS, AT interfaces mostly for debug
|
|
|
|
At() at.Port // Send
|
|
|
|
Gps() gps.Gps // Update, GetData, GetStatus
|
|
|
|
Sms() sms.Sms // Send, ReadNew
|
2024-07-29 13:51:54 +00:00
|
|
|
|
2024-07-25 13:58:09 +00:00
|
|
|
io.Closer
|
2024-07-18 16:34:26 +00:00
|
|
|
}
|
|
|
|
|
2024-07-23 16:02:28 +00:00
|
|
|
func New(logger *log.Logger) Modem {
|
2024-07-18 16:34:26 +00:00
|
|
|
return &modem{
|
2024-07-31 11:51:29 +00:00
|
|
|
logger: logger,
|
|
|
|
baudrate: 115200,
|
|
|
|
onOffPin: gpio.New(log.New(logger.Writer(), "gpio", log.LstdFlags), 6),
|
|
|
|
|
2024-07-18 16:34:26 +00:00
|
|
|
lastUpdateTime: time.Now(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *modem) Init() error {
|
2024-08-06 18:10:24 +00:00
|
|
|
m.mutex.Lock()
|
|
|
|
defer m.mutex.Unlock()
|
|
|
|
|
2024-07-21 13:05:09 +00:00
|
|
|
// Turn module on
|
2024-07-27 13:01:27 +00:00
|
|
|
m.logger.Println("=============================== Turn on module")
|
2024-07-23 19:04:15 +00:00
|
|
|
if err := m.onOffPin.Init(); err != nil {
|
|
|
|
return fmt.Errorf("gpio pin init: %w", err)
|
|
|
|
}
|
2024-07-21 13:05:09 +00:00
|
|
|
|
2024-07-23 14:59:26 +00:00
|
|
|
// Search
|
|
|
|
m.logger.Println("=============================== Search")
|
2024-07-21 13:05:09 +00:00
|
|
|
// Soft search
|
2024-07-23 16:02:28 +00:00
|
|
|
if err := m.searchPort(true); err != nil {
|
2024-07-18 16:34:26 +00:00
|
|
|
return fmt.Errorf("soft port search: %w", err)
|
|
|
|
}
|
2024-07-23 14:59:26 +00:00
|
|
|
// Wide search
|
2024-07-21 13:05:09 +00:00
|
|
|
if m.port == nil {
|
2024-07-23 16:02:28 +00:00
|
|
|
if err := m.searchPort(false); err != nil {
|
2024-07-18 16:34:26 +00:00
|
|
|
return fmt.Errorf("not soft port search: %w", err)
|
|
|
|
}
|
|
|
|
}
|
2024-07-21 13:05:09 +00:00
|
|
|
if m.port == nil {
|
2024-07-23 16:02:28 +00:00
|
|
|
return fmt.Errorf("no port is detected")
|
2024-07-18 16:34:26 +00:00
|
|
|
}
|
2024-07-21 13:05:09 +00:00
|
|
|
|
|
|
|
// Connect
|
2024-07-23 14:59:26 +00:00
|
|
|
m.logger.Println("=============================== Connect")
|
2024-07-25 13:58:09 +00:00
|
|
|
if err := m.connect(); err != nil {
|
2024-07-18 16:34:26 +00:00
|
|
|
return fmt.Errorf("connect: %w", err)
|
|
|
|
}
|
2024-07-23 14:26:24 +00:00
|
|
|
|
2024-07-31 11:51:29 +00:00
|
|
|
// Init submodules
|
2024-08-07 08:35:06 +00:00
|
|
|
submodulesLogger := m.logger.Writer() // FOR more logs
|
|
|
|
// submodulesLogger := io.Discard // FOR less logs
|
2024-08-06 17:37:20 +00:00
|
|
|
|
2024-08-01 16:34:58 +00:00
|
|
|
m.logger.Println("=============================== Init submodules")
|
2024-08-09 08:42:55 +00:00
|
|
|
//m.ic = internet.New(log.New(submodulesLogger, "modem-internet : ", log.LstdFlags), m.port)
|
|
|
|
//if err := m.ic.Init(); err != nil {
|
|
|
|
// m.logger.Printf("\x1b[38;2;255;0;0mInternet: %s\x1b[38;2;255;255;255m\n", err.Error())
|
|
|
|
//} else {
|
|
|
|
// m.logger.Println("\x1b[38;2;0;255;0mInternet OK\x1b[38;2;255;255;255m")
|
|
|
|
//}
|
|
|
|
//
|
|
|
|
//m.sms = sms.New(log.New(submodulesLogger, "modem-sms : ", log.LstdFlags), m.port)
|
|
|
|
//if err := m.sms.Init(); err != nil {
|
|
|
|
// m.logger.Printf("\x1b[38;2;255;0;0mSMS: %s\x1b[38;2;255;255;255m\n", err.Error())
|
|
|
|
//} else {
|
|
|
|
// m.logger.Println("\x1b[38;2;0;255;0mSMS OK\x1b[38;2;255;255;255m")
|
|
|
|
//}
|
2024-08-06 17:37:20 +00:00
|
|
|
|
|
|
|
m.gps = gps.New(log.New(submodulesLogger, "modem-gps : ", log.LstdFlags), m.port)
|
2024-07-31 11:51:29 +00:00
|
|
|
if err := m.gps.Init(); err != nil {
|
2024-08-06 17:37:20 +00:00
|
|
|
m.logger.Printf("\x1b[38;2;255;0;0mgps init %w\x1b[38;2;255;255;255m\n", err)
|
|
|
|
} else {
|
|
|
|
m.logger.Println("\x1b[38;2;0;255;0mGPS OK\x1b[38;2;255;255;255m")
|
2024-07-31 11:51:29 +00:00
|
|
|
}
|
2024-08-01 16:34:58 +00:00
|
|
|
|
|
|
|
// Tests
|
2024-08-06 17:37:20 +00:00
|
|
|
// GPS works fine but almost always there is no signal
|
|
|
|
// m.logger.Println("=============================== Test")
|
|
|
|
// if err := m.testGPS(); err != nil {
|
|
|
|
// return fmt.Errorf("testGPS: %w", err)
|
|
|
|
// }
|
2024-07-31 11:51:29 +00:00
|
|
|
|
2024-07-18 16:34:26 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-07-23 16:02:28 +00:00
|
|
|
func (m *modem) Update() error {
|
2024-08-06 18:10:24 +00:00
|
|
|
m.mutex.Lock()
|
|
|
|
defer m.mutex.Unlock()
|
|
|
|
|
2024-08-06 17:37:20 +00:00
|
|
|
if !m.IsConnected() {
|
2024-07-23 16:02:28 +00:00
|
|
|
m.logger.Println("No connection to module")
|
|
|
|
return nil
|
|
|
|
}
|
2024-08-01 16:34:58 +00:00
|
|
|
m.logger.Println("Update", m.gps)
|
2024-07-31 11:51:29 +00:00
|
|
|
if err := m.gps.Update(); err != nil {
|
2024-08-01 16:34:58 +00:00
|
|
|
m.logger.Println("gps update:", err.Error())
|
2024-07-23 16:02:28 +00:00
|
|
|
}
|
2024-08-06 17:37:20 +00:00
|
|
|
// Read new messages
|
|
|
|
|
2024-07-23 16:02:28 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-07-31 11:51:29 +00:00
|
|
|
func (m *modem) GetData() ModemData {
|
2024-08-06 18:10:24 +00:00
|
|
|
m.mutex.Lock()
|
|
|
|
defer m.mutex.Unlock()
|
|
|
|
|
2024-07-25 13:58:09 +00:00
|
|
|
return ModemData{
|
2024-07-31 11:51:29 +00:00
|
|
|
Port: m.port.GetName(),
|
|
|
|
Data: m.gps.GetData(),
|
2024-07-23 16:02:28 +00:00
|
|
|
}
|
2024-07-25 13:58:09 +00:00
|
|
|
}
|
2024-07-23 16:02:28 +00:00
|
|
|
|
2024-08-07 14:34:56 +00:00
|
|
|
func (m *modem) PowerOn() error {
|
|
|
|
m.onOffPin.PowerOn() // DEBUG do not want to wait 30 seconds
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *modem) PowerOff() error {
|
|
|
|
_, err := m.At().Send("AT+CPOF")
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-08-06 17:37:20 +00:00
|
|
|
func (m *modem) Sms() sms.Sms {
|
2024-07-29 13:51:54 +00:00
|
|
|
return m.sms
|
|
|
|
}
|
|
|
|
|
2024-07-31 11:51:29 +00:00
|
|
|
func (m *modem) Gps() gps.Gps {
|
|
|
|
return m.gps
|
|
|
|
}
|
|
|
|
|
2024-07-29 17:03:22 +00:00
|
|
|
func (m *modem) At() at.Port {
|
|
|
|
return m.port
|
|
|
|
}
|
|
|
|
|
2024-08-06 17:37:20 +00:00
|
|
|
func (m *modem) Close() error { // I can't return error so I log it
|
2024-08-06 18:10:24 +00:00
|
|
|
m.mutex.Lock()
|
|
|
|
defer m.mutex.Unlock()
|
|
|
|
|
2024-07-29 13:51:54 +00:00
|
|
|
if err := m.sms.Close(); err != nil {
|
2024-08-06 17:37:20 +00:00
|
|
|
m.logger.Printf("\x1b[38;2;255;0;0mclose sms error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
2024-07-29 13:51:54 +00:00
|
|
|
}
|
|
|
|
|
2024-07-25 13:58:09 +00:00
|
|
|
if err := m.port.Close(); err != nil {
|
2024-08-06 17:37:20 +00:00
|
|
|
m.logger.Printf("\x1b[38;2;255;0;0mclose serial port error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
2024-07-25 13:58:09 +00:00
|
|
|
}
|
|
|
|
if err := m.onOffPin.Close(); err != nil {
|
2024-08-06 17:37:20 +00:00
|
|
|
m.logger.Printf("\x1b[38;2;255;0;0mclose gpio pin error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
2024-07-23 16:02:28 +00:00
|
|
|
}
|
2024-07-27 13:01:27 +00:00
|
|
|
if err := m.ic.Close(); err != nil {
|
2024-08-06 17:37:20 +00:00
|
|
|
m.logger.Printf("\x1b[38;2;255;0;0mclose internet connection error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
2024-07-27 13:01:27 +00:00
|
|
|
}
|
|
|
|
|
2024-07-23 16:02:28 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-08-06 17:37:20 +00:00
|
|
|
///////////// Private functions
|
|
|
|
|
2024-07-25 13:58:09 +00:00
|
|
|
func (m *modem) connect() error {
|
2024-07-27 13:01:27 +00:00
|
|
|
if m.port == nil {
|
2024-07-25 13:58:09 +00:00
|
|
|
return fmt.Errorf("port is not defined")
|
|
|
|
}
|
|
|
|
return m.port.Connect()
|
2024-07-23 16:02:28 +00:00
|
|
|
}
|
|
|
|
|
2024-07-25 13:58:09 +00:00
|
|
|
func (m *modem) disconnect() error {
|
2024-07-27 13:01:27 +00:00
|
|
|
if m.port == nil {
|
2024-07-25 13:58:09 +00:00
|
|
|
return fmt.Errorf("port is not defined")
|
|
|
|
}
|
|
|
|
return m.port.Disconnect()
|
2024-07-23 16:02:28 +00:00
|
|
|
}
|
|
|
|
|
2024-08-06 17:37:20 +00:00
|
|
|
func (m *modem) IsConnected() bool {
|
2024-07-25 13:58:09 +00:00
|
|
|
if m.port != nil {
|
|
|
|
return m.port.IsConnected()
|
2024-07-23 16:02:28 +00:00
|
|
|
}
|
2024-07-25 13:58:09 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *modem) testGPS() error {
|
|
|
|
m.logger.Println("Testing GPS")
|
|
|
|
|
|
|
|
if err := m.Update(); err != nil {
|
|
|
|
return fmt.Errorf("update: %w", err)
|
2024-07-23 16:02:28 +00:00
|
|
|
}
|
2024-07-25 13:58:09 +00:00
|
|
|
|
|
|
|
m.logger.Println("Current coords:", m.getShortInfo())
|
|
|
|
return nil
|
2024-07-23 16:02:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Difference: I do not set \n at the end of string
|
2024-07-25 13:58:09 +00:00
|
|
|
func (m *modem) getShortInfo() string {
|
2024-07-31 11:51:29 +00:00
|
|
|
d := m.gps.GetData()
|
|
|
|
return fmt.Sprintf("%f,%s,%f,%s", d.Latitude, d.LatitudeIndicator, d.Longitude, d.LongitudeIndicator)
|
2024-07-23 16:02:28 +00:00
|
|
|
}
|
|
|
|
|
2024-07-25 13:58:09 +00:00
|
|
|
func (m *modem) saveGPS(path string) error {
|
2024-07-23 16:02:28 +00:00
|
|
|
f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("open file: %w", err)
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
2024-07-25 13:58:09 +00:00
|
|
|
if _, err = f.WriteString(m.getShortInfo()); err != nil {
|
2024-07-23 16:02:28 +00:00
|
|
|
return fmt.Errorf("write file: %W", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2024-07-29 17:03:22 +00:00
|
|
|
|
2024-08-06 17:37:20 +00:00
|
|
|
// Short way to send command
|
|
|
|
func (m *modem) printCmd(cmd string) {
|
|
|
|
if resp, err := m.port.Send(cmd); err != nil {
|
|
|
|
m.logger.Println("FAILED TO SEND REQ", cmd, ":", err.Error())
|
|
|
|
} else {
|
|
|
|
_ = resp
|
|
|
|
// m.logger.Println("CMD", cmd, ":", resp)
|
2024-07-23 19:04:15 +00:00
|
|
|
}
|
|
|
|
}
|
2024-07-23 16:02:28 +00:00
|
|
|
|
2024-08-06 17:37:20 +00:00
|
|
|
// Some required commands before checking port
|
2024-08-04 12:59:58 +00:00
|
|
|
func (m *modem) setupPort() error {
|
|
|
|
// Reset input
|
|
|
|
if err := m.port.SerialPort().ResetInputBuffer(); err != nil {
|
|
|
|
return fmt.Errorf("reset input buffer: %w", err)
|
|
|
|
}
|
|
|
|
// Reset output
|
|
|
|
if err := m.port.SerialPort().ResetOutputBuffer(); err != nil {
|
|
|
|
return fmt.Errorf("reset output buffer: %w", err)
|
|
|
|
}
|
|
|
|
|
2024-08-06 17:37:20 +00:00
|
|
|
// These commands ensure that correct modes are set
|
|
|
|
m.printCmd("ATE0") // Sometimes enables echo mode
|
|
|
|
m.printCmd("AT+CGPSFTM=0") // Sometimes does not turn off nmea
|
|
|
|
m.printCmd("AT+CMEE=2") // Turn on errors describtion
|
2024-08-04 12:59:58 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-07-23 16:02:28 +00:00
|
|
|
func (m *modem) checkPort(portName string) (outErr error) {
|
|
|
|
defer func() {
|
|
|
|
if outErr != nil { // Clear port if there is error
|
|
|
|
m.port = nil
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2024-07-21 13:05:09 +00:00
|
|
|
// Check device for existance
|
|
|
|
if _, err := os.Stat(portName); err != nil {
|
|
|
|
return fmt.Errorf("device does not exist")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check serial connection
|
|
|
|
// Connect
|
2024-07-23 16:02:28 +00:00
|
|
|
m.port = at.New(m.logger, portName, m.baudrate)
|
2024-07-22 17:37:02 +00:00
|
|
|
if err := m.port.Connect(); err != nil {
|
2024-07-21 13:05:09 +00:00
|
|
|
return fmt.Errorf("connect: %w", err)
|
|
|
|
}
|
2024-07-22 17:37:02 +00:00
|
|
|
defer m.port.Disconnect() // Do not bother about errors...
|
2024-07-21 13:05:09 +00:00
|
|
|
|
2024-08-06 18:10:24 +00:00
|
|
|
// To filter dead ports
|
|
|
|
if _, err := m.port.Send("AT"); err != nil {
|
|
|
|
return fmt.Errorf("ping error: %w", err)
|
|
|
|
}
|
|
|
|
|
2024-08-04 12:59:58 +00:00
|
|
|
if err := m.setupPort(); err != nil {
|
|
|
|
return fmt.Errorf("setup port: %w", err)
|
2024-07-23 19:04:15 +00:00
|
|
|
}
|
|
|
|
|
2024-07-21 13:05:09 +00:00
|
|
|
// Ping
|
2024-07-23 14:59:26 +00:00
|
|
|
m.logger.Println("Ping...")
|
2024-07-23 16:02:28 +00:00
|
|
|
if err := m.ping(); err != nil {
|
2024-07-21 13:05:09 +00:00
|
|
|
return fmt.Errorf("ping error: %w", err)
|
|
|
|
}
|
2024-07-23 19:04:15 +00:00
|
|
|
m.logger.Println("\x1b[38;2;0;255;0mOK\x1b[38;2;255;255;255m")
|
2024-07-21 13:05:09 +00:00
|
|
|
|
|
|
|
// Check model
|
2024-07-23 14:59:26 +00:00
|
|
|
m.logger.Println("Check model...")
|
2024-07-23 09:22:53 +00:00
|
|
|
resp, err := m.port.Send("AT+CGMM")
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("get model: %w", err)
|
|
|
|
}
|
|
|
|
if !resp.Check() {
|
2024-08-04 12:59:58 +00:00
|
|
|
return fmt.Errorf("get model: error response: %s", resp)
|
2024-07-23 09:22:53 +00:00
|
|
|
}
|
2024-07-23 14:26:24 +00:00
|
|
|
model := strings.Split(resp.String(), "\n")[0]
|
2024-07-21 13:05:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("get model: %w", err)
|
|
|
|
}
|
2024-07-23 14:26:24 +00:00
|
|
|
rightModel := "SIMCOM_SIM7600E-H"
|
2024-07-23 14:59:26 +00:00
|
|
|
// m.logger.Printf("[% x]\n [% x]", []byte("SIMCOM_SIM7600E-H"), []byte(model))
|
2024-07-29 15:53:55 +00:00
|
|
|
if len(model) >= len(rightModel) && model[:len(rightModel)] != rightModel {
|
2024-07-21 13:05:09 +00:00
|
|
|
return fmt.Errorf("invalid modem model: %s", model)
|
|
|
|
}
|
2024-07-23 19:04:15 +00:00
|
|
|
m.logger.Println("\x1b[38;2;0;255;0mOK\x1b[38;2;255;255;255m")
|
2024-07-21 13:05:09 +00:00
|
|
|
return nil
|
|
|
|
}
|
2024-07-18 16:34:26 +00:00
|
|
|
|
2024-07-23 16:02:28 +00:00
|
|
|
func (m *modem) searchPort(isSoft bool) error {
|
2024-07-18 16:34:26 +00:00
|
|
|
// Get ports
|
2024-07-21 13:05:09 +00:00
|
|
|
ports := []string{"ttyUSB1", "ttyUSB2", "ttyUSB3"}
|
|
|
|
if !isSoft {
|
2024-07-25 13:58:09 +00:00
|
|
|
ps, err := getTtyDevices()
|
2024-07-18 16:34:26 +00:00
|
|
|
if err != nil {
|
2024-07-21 13:05:09 +00:00
|
|
|
fmt.Errorf("get serial devices: %w", err)
|
2024-07-18 16:34:26 +00:00
|
|
|
}
|
2024-07-21 13:05:09 +00:00
|
|
|
ports = ps
|
2024-07-18 16:34:26 +00:00
|
|
|
}
|
2024-07-21 13:05:09 +00:00
|
|
|
|
2024-07-18 16:34:26 +00:00
|
|
|
// Check ports
|
2024-07-21 13:05:09 +00:00
|
|
|
SearchLoop:
|
2024-07-18 16:34:26 +00:00
|
|
|
for _, p := range ports {
|
2024-07-23 14:59:26 +00:00
|
|
|
m.logger.Printf("Checking port %s ...\n", p)
|
2024-07-18 16:34:26 +00:00
|
|
|
|
2024-07-21 13:05:09 +00:00
|
|
|
if err := m.checkPort("/dev/" + p); err != nil {
|
2024-07-23 19:04:15 +00:00
|
|
|
m.logger.Printf("\x1b[38;2;255;0;0mCheck failed: %s\x1b[38;2;255;255;255m\n", err.Error())
|
2024-07-21 13:05:09 +00:00
|
|
|
continue SearchLoop
|
2024-07-18 16:34:26 +00:00
|
|
|
}
|
|
|
|
|
2024-07-23 14:59:26 +00:00
|
|
|
m.logger.Print("Found modem on port: ", p)
|
2024-07-23 16:02:28 +00:00
|
|
|
m.port = at.New(m.logger, "/dev/"+p, m.baudrate)
|
2024-07-18 16:34:26 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-07-23 16:02:28 +00:00
|
|
|
func (m *modem) ping() error {
|
2024-07-23 09:22:53 +00:00
|
|
|
resp, err := m.port.Send("AT")
|
|
|
|
if err != nil {
|
2024-08-04 12:59:58 +00:00
|
|
|
return fmt.Errorf("AT request: %w", err)
|
2024-07-23 09:22:53 +00:00
|
|
|
}
|
2024-07-23 14:26:24 +00:00
|
|
|
if !resp.Check() {
|
2024-08-04 12:59:58 +00:00
|
|
|
return fmt.Errorf("AT request: error response: %s", resp)
|
2024-07-23 09:22:53 +00:00
|
|
|
}
|
|
|
|
return nil
|
2024-07-18 16:34:26 +00:00
|
|
|
}
|
|
|
|
|
2024-07-25 13:58:09 +00:00
|
|
|
func getTtyDevices() ([]string, error) {
|
2024-07-21 13:05:09 +00:00
|
|
|
// Get ports
|
|
|
|
/**/
|
2024-07-25 13:58:09 +00:00
|
|
|
out, err := exec.Command("ls", "--", "/dev/tty[!0-9]*").Output()
|
2024-07-21 13:05:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("execute ls command: %w", err)
|
|
|
|
}
|
2024-07-25 13:58:09 +00:00
|
|
|
ports := strings.Split(string(out), "\n")
|
|
|
|
return ports, nil
|
2024-07-21 13:05:09 +00:00
|
|
|
}
|
|
|
|
|
2024-07-18 16:34:26 +00:00
|
|
|
/*
|
|
|
|
TODOs:
|
|
|
|
maybe to store read/write buf in obj
|
|
|
|
QUESTIONS:
|
2024-07-21 13:05:09 +00:00
|
|
|
JSON why you clamp
|
2024-07-18 16:34:26 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
*/
|