Added GetTime. Added independent internet port. Debugged internet connection.
This commit is contained in:
parent
5059814d39
commit
5065cfdfca
@ -42,14 +42,14 @@ checkLoop:
|
|||||||
}
|
}
|
||||||
st.GotResponses = true
|
st.GotResponses = true
|
||||||
|
|
||||||
g.logger.Println("NMEA check:", s)
|
// g.logger.Println("NMEA check:", s)
|
||||||
values := strings.Split(s, ",")
|
values := strings.Split(s, ",")
|
||||||
if len(values[0]) != 6 {
|
if len(values[0]) != 6 {
|
||||||
return StatusNil, fmt.Errorf("nmea invalid sentence: %s", s)
|
return StatusNil, fmt.Errorf("nmea invalid sentence: %s", s)
|
||||||
}
|
}
|
||||||
switch values[0][3:] { // Switch by content
|
switch values[0][3:] { // Switch by content
|
||||||
case "GSV": // Any satelites
|
case "GSV": // Any satelites
|
||||||
g.logger.Println("check GSV")
|
// g.logger.Println("check GSV")
|
||||||
// Check len
|
// Check len
|
||||||
if len(values) < 17 {
|
if len(values) < 17 {
|
||||||
g.logger.Println("GSV too small values")
|
g.logger.Println("GSV too small values")
|
||||||
@ -83,7 +83,7 @@ checkLoop:
|
|||||||
}
|
}
|
||||||
st.FoundSatelitesCount = satCount
|
st.FoundSatelitesCount = satCount
|
||||||
case "GSA": // Active satelites
|
case "GSA": // Active satelites
|
||||||
g.logger.Println("check GSA")
|
// g.logger.Println("check GSA")
|
||||||
|
|
||||||
// Check len
|
// Check len
|
||||||
if len(values) < 17 {
|
if len(values) < 17 {
|
||||||
@ -107,7 +107,7 @@ checkLoop:
|
|||||||
}
|
}
|
||||||
st.ActiveSatelitesCount = max(st.ActiveSatelitesCount, count)
|
st.ActiveSatelitesCount = max(st.ActiveSatelitesCount, count)
|
||||||
case "RMC": // Minimum GPS data
|
case "RMC": // Minimum GPS data
|
||||||
g.logger.Println("check RMC")
|
// g.logger.Println("check RMC")
|
||||||
// Check len
|
// Check len
|
||||||
if len(values) < 12 {
|
if len(values) < 12 {
|
||||||
g.logger.Println("RMC too small values")
|
g.logger.Println("RMC too small values")
|
||||||
@ -125,7 +125,7 @@ checkLoop:
|
|||||||
st.IsValidData = true
|
st.IsValidData = true
|
||||||
}
|
}
|
||||||
case "GST":
|
case "GST":
|
||||||
g.logger.Println("check GST")
|
// g.logger.Println("check GST")
|
||||||
// Check len
|
// Check len
|
||||||
if len(values) < 8 {
|
if len(values) < 8 {
|
||||||
g.logger.Println("GST too small values")
|
g.logger.Println("GST too small values")
|
||||||
|
@ -8,125 +8,147 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gitea.unprism.ru/KRBL/sim-modem/api/modem/at"
|
"gitea.unprism.ru/KRBL/sim-modem/api/modem/at"
|
||||||
"gitea.unprism.ru/KRBL/sim-modem/api/modem/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var apns = map[string]string{
|
|
||||||
"Tinkoff": "m.tinkoff",
|
|
||||||
}
|
|
||||||
|
|
||||||
const pppConfigName = "annalistnet"
|
|
||||||
const pppConfig = `
|
|
||||||
# Annalist project custom internet connection
|
|
||||||
|
|
||||||
# APN:
|
|
||||||
connect "/usr/sbin/chat -v -f /etc/chatscripts/gprs -T %s"
|
|
||||||
|
|
||||||
# Port:
|
|
||||||
%s
|
|
||||||
|
|
||||||
# Baudrate:
|
|
||||||
%d
|
|
||||||
|
|
||||||
noipdefault
|
|
||||||
usepeerdns
|
|
||||||
defaultroute
|
|
||||||
persist
|
|
||||||
noauth
|
|
||||||
nocrtscts
|
|
||||||
local
|
|
||||||
`
|
|
||||||
|
|
||||||
type conn struct {
|
type conn struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
port at.Port
|
port at.Port
|
||||||
|
|
||||||
|
pppPort string
|
||||||
|
|
||||||
|
isConnectExecuted bool
|
||||||
|
isInited bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Conn interface {
|
type Conn interface {
|
||||||
Init() error
|
Init(pppPort string) error
|
||||||
|
|
||||||
Connect() error
|
Connect() error
|
||||||
Disconnect() error
|
Disconnect() error
|
||||||
Ping() bool // Is connected
|
|
||||||
|
IsConnected() bool // Check interface existance
|
||||||
|
Ping() error
|
||||||
|
|
||||||
io.Closer
|
io.Closer
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(logger *log.Logger, port at.Port) Conn {
|
func New(logger *log.Logger, port at.Port) Conn {
|
||||||
return &conn{
|
return &conn{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
port: port,
|
port: port,
|
||||||
|
isConnectExecuted: false,
|
||||||
|
isInited: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Connect() error {
|
func (c *conn) Init(pppPort string) error {
|
||||||
if ok, err := utils.CheckService(c.port, c.logger); err != nil || !ok {
|
c.pppPort = pppPort
|
||||||
if err != nil {
|
// Setup only setup
|
||||||
return fmt.Errorf("check service: %w", err)
|
if err := c.setup(); err != nil {
|
||||||
}
|
return fmt.Errorf("setup: %w", err)
|
||||||
return fmt.Errorf("no service")
|
|
||||||
}
|
}
|
||||||
|
c.isInited = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *conn) Connect() error {
|
||||||
|
if !c.isInited {
|
||||||
|
return fmt.Errorf("internet submodule is not inited")
|
||||||
|
}
|
||||||
|
// Check is already connected
|
||||||
|
if c.isConnectExecuted {
|
||||||
|
return fmt.Errorf("already connected")
|
||||||
|
}
|
||||||
|
// Check signal
|
||||||
|
// if ok, err := utils.CheckService(c.port, c.logger); err != nil || !ok {
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("check service: %w", err)
|
||||||
|
// }
|
||||||
|
// return fmt.Errorf("no service")
|
||||||
|
// }
|
||||||
|
|
||||||
resp, err := exec.Command("pon", pppConfigName).Output()
|
resp, err := exec.Command("pon", pppConfigName).Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("execute connect cmd: %w", err)
|
return fmt.Errorf("execute pon cmd: %w", err)
|
||||||
}
|
}
|
||||||
c.logger.Println("DEBUG pon response:", string(resp))
|
if len(resp) > 0 {
|
||||||
|
c.logger.Println("pon response:", string(resp))
|
||||||
|
}
|
||||||
|
c.isConnectExecuted = true
|
||||||
|
|
||||||
|
// Set default route
|
||||||
|
|
||||||
|
c.logger.Println("\x1b[38;2;0;255;0mInternet connected.\x1b[38;2;255;255;255m")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Disconnect() error {
|
func (c *conn) Disconnect() error {
|
||||||
|
// return nil // Temporary do not turn off inet
|
||||||
|
if !c.isConnectExecuted {
|
||||||
|
return nil
|
||||||
|
// return fmt.Errorf("internet is not connected")
|
||||||
|
}
|
||||||
|
c.isConnectExecuted = false
|
||||||
resp, err := exec.Command("poff", pppConfigName).Output()
|
resp, err := exec.Command("poff", pppConfigName).Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("execute disconnect cmd: %w", err)
|
return fmt.Errorf("execute poff cmd: %w", err)
|
||||||
}
|
}
|
||||||
c.logger.Println("DEBUG poff response:", string(resp))
|
if len(resp) > 0 {
|
||||||
|
c.logger.Println("poff response:", string(resp))
|
||||||
|
}
|
||||||
|
c.isConnectExecuted = false
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Init() error {
|
func (c *conn) Ping() error {
|
||||||
// Setup
|
|
||||||
if err := c.setup(); err != nil {
|
|
||||||
return fmt.Errorf("setup: %w", err)
|
|
||||||
}
|
|
||||||
// // Connect
|
|
||||||
// c.logger.Println("Connect...")
|
|
||||||
// if err := c.Connect(); err != nil {
|
|
||||||
// return fmt.Errorf("connect: %w", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //DEBUG
|
|
||||||
// resp, err := exec.Command("ifconfig").Output()
|
|
||||||
// if err != nil {
|
|
||||||
// return fmt.Errorf("execute ifconfig cmd: %w", err)
|
|
||||||
// }
|
|
||||||
// c.logger.Println("DEBUG ifconfig resp:", string(resp))
|
|
||||||
|
|
||||||
// // Test connectin using Ping
|
|
||||||
// c.logger.Println("Test...")
|
|
||||||
// if !c.Ping() {
|
|
||||||
// return fmt.Errorf("ping failed")
|
|
||||||
// }
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *conn) Ping() bool {
|
|
||||||
// Test - try to connect to Google DNS
|
// Test - try to connect to Google DNS
|
||||||
// ping -I ppp0 8.8.8.8
|
// ping -I ppp0 8.8.8.8
|
||||||
resp, err := exec.Command("ping", "8.8.8.8").Output()
|
resp, err := exec.Command("ping", "8.8.8.8").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Println("Ping 1 cmd error:", err)
|
c.logger.Println("Ping default interface cmd error:", err)
|
||||||
}
|
}
|
||||||
c.logger.Println("Ping 1 resp:", string(resp))
|
c.logger.Println("Ping default interface resp:", string(resp))
|
||||||
|
|
||||||
resp, err = exec.Command("ping", "-I", "ppp0", "8.8.8.8").Output()
|
resp, err = exec.Command("ping", "-I", "ppp0", "8.8.8.8").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Println("Ping 2 cmd error:", err)
|
c.logger.Println("Ping ppp0 interface cmd error:", err)
|
||||||
}
|
}
|
||||||
c.logger.Println("Ping 2 resp:", string(resp))
|
c.logger.Println("Ping ppp0 interface resp:", string(resp))
|
||||||
|
|
||||||
return !(strings.Contains(string(resp), "Destination Host Unreachable") || strings.Contains(string(resp), "Destination Net Unreachable")) // tmp solution
|
if strings.Contains(string(resp), "Destination Host Unreachable") || strings.Contains(string(resp), "Destination Net Unreachable") {
|
||||||
|
return fmt.Errorf("ping response: %s", string(resp))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *conn) IsConnected() bool {
|
||||||
|
if !c.isConnectExecuted {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// Make "ifconfig" request
|
||||||
|
resp, err := exec.Command("ifconfig").Output()
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Println("ifconfig cmd error:", err.Error())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(resp), "\n")
|
||||||
|
for _, l := range lines {
|
||||||
|
if len(l) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if l[0] == ' ' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
interfaceName := strings.Split(l, ":")[0]
|
||||||
|
if interfaceName == "ppp0" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false // Did not found
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Close() error {
|
func (c *conn) Close() error {
|
||||||
|
c.isInited = false
|
||||||
if err := c.Disconnect(); err != nil {
|
if err := c.Disconnect(); err != nil {
|
||||||
return fmt.Errorf("diconnect: %w", err)
|
return fmt.Errorf("diconnect: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -9,27 +9,40 @@ import (
|
|||||||
"gitea.unprism.ru/KRBL/sim-modem/api/modem/utils"
|
"gitea.unprism.ru/KRBL/sim-modem/api/modem/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var apns = map[string]string{
|
||||||
|
"Tinkoff": "m.tinkoff",
|
||||||
|
"Megafon": "internet",
|
||||||
|
"BeeLine": "internet.beeline.ru",
|
||||||
|
}
|
||||||
|
|
||||||
|
const pppConfigName = "annalistnet"
|
||||||
|
const pppConfig = `
|
||||||
|
# Annalist project custom internet connection
|
||||||
|
|
||||||
|
# APN:
|
||||||
|
connect "/usr/sbin/chat -v -f /etc/chatscripts/gprs -T %s"
|
||||||
|
|
||||||
|
# Port:
|
||||||
|
%s
|
||||||
|
|
||||||
|
# Baudrate:
|
||||||
|
%d
|
||||||
|
|
||||||
|
noipdefault
|
||||||
|
usepeerdns
|
||||||
|
defaultroute
|
||||||
|
persist
|
||||||
|
noauth
|
||||||
|
nocrtscts
|
||||||
|
local
|
||||||
|
`
|
||||||
|
|
||||||
func (c *conn) setup() error {
|
func (c *conn) setup() error {
|
||||||
c.logger.Println("Check requirenments...")
|
|
||||||
if err := c.checkReqs(); err != nil {
|
if err := c.checkReqs(); err != nil {
|
||||||
return fmt.Errorf("check requirenments: %w", err)
|
return fmt.Errorf("check requirenments: %w", err)
|
||||||
}
|
}
|
||||||
// DEBUG show networks and signal
|
|
||||||
resp, err := c.port.Send("AT+COPS?")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("AT+COPS? request: %w", err)
|
|
||||||
}
|
|
||||||
c.logger.Println("DEBUG networks:", resp)
|
|
||||||
|
|
||||||
resp, err = c.port.Send("AT+CSQ")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("AT+CSQ request: %w", err)
|
|
||||||
}
|
|
||||||
c.logger.Println("DEBUG signal quality:", resp)
|
|
||||||
|
|
||||||
// Configure ppp
|
// Configure ppp
|
||||||
// what is better ASK If /etc/ppp/peers/annalistnet not exists
|
// what is better ASK If /etc/ppp/peers/annalistnet not exists
|
||||||
c.logger.Println("Configure ppp...")
|
|
||||||
if err := c.configurePPP(); err != nil {
|
if err := c.configurePPP(); err != nil {
|
||||||
return fmt.Errorf("configure ppp: %w", err)
|
return fmt.Errorf("configure ppp: %w", err)
|
||||||
}
|
}
|
||||||
@ -75,9 +88,8 @@ func (c *conn) ensurePackage(pname string) error {
|
|||||||
|
|
||||||
func (c *conn) checkPackageExist(pname string) bool {
|
func (c *conn) checkPackageExist(pname string) bool {
|
||||||
resp, err := exec.Command("apt-mark", "showmanual", pname).Output()
|
resp, err := exec.Command("apt-mark", "showmanual", pname).Output()
|
||||||
c.logger.Println("CHECK:", resp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Println("CHECK PACKAGE ERROR: ", err.Error())
|
c.logger.Println("check package error: ", err.Error())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return string(resp[:len(pname)]) == pname
|
return string(resp[:len(pname)]) == pname
|
||||||
@ -103,8 +115,8 @@ func (c *conn) configurePPP() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make config
|
// Make config
|
||||||
c.logger.Printf("Config values: %s, %s, %d", apn, c.port.GetName(), c.port.GetBaudrate())
|
c.logger.Printf("Config ppp values: %s, %s, %d", apn, c.pppPort, c.port.GetBaudrate())
|
||||||
config := fmt.Sprintf(pppConfig, apn, c.port.GetName(), c.port.GetBaudrate())
|
config := fmt.Sprintf(pppConfig, apn, c.pppPort, c.port.GetBaudrate())
|
||||||
|
|
||||||
// Write to file
|
// Write to file
|
||||||
f, err := os.OpenFile("/etc/ppp/peers/"+pppConfigName, os.O_CREATE|os.O_WRONLY, 0666)
|
f, err := os.OpenFile("/etc/ppp/peers/"+pppConfigName, os.O_CREATE|os.O_WRONLY, 0666)
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -17,6 +18,9 @@ import (
|
|||||||
"gitea.unprism.ru/KRBL/sim-modem/api/modem/sms"
|
"gitea.unprism.ru/KRBL/sim-modem/api/modem/sms"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// yy/MM/dd,hh:mm:ss+zzzz
|
||||||
|
const timeLayout = "06/01/02,15:04:05-0700"
|
||||||
|
|
||||||
type ModemData struct {
|
type ModemData struct {
|
||||||
Port string `json:"Port"`
|
Port string `json:"Port"`
|
||||||
gps.Data
|
gps.Data
|
||||||
@ -53,14 +57,16 @@ type Modem interface {
|
|||||||
IsConnected() bool
|
IsConnected() bool
|
||||||
Update() error
|
Update() error
|
||||||
GetData() ModemData
|
GetData() ModemData
|
||||||
|
GetTime() (time.Time, error)
|
||||||
|
|
||||||
PowerOn() error
|
PowerOn() error
|
||||||
PowerOff() error
|
PowerOff() error
|
||||||
|
|
||||||
// Access to SMS, GPS, AT interfaces mostly for debug
|
// Access to SMS, GPS, AT interfaces mostly for debug
|
||||||
At() at.Port // Send
|
At() at.Port // Send
|
||||||
Gps() gps.Gps // Update, GetData, GetStatus
|
Gps() gps.Gps // Update, GetData, GetStatus
|
||||||
Sms() sms.Sms // Send, ReadNew
|
Sms() sms.Sms // Send, ReadNew
|
||||||
|
Ic() internet.Conn // Connect, Disconnect
|
||||||
|
|
||||||
io.Closer
|
io.Closer
|
||||||
}
|
}
|
||||||
@ -80,29 +86,41 @@ func (m *modem) Init() error {
|
|||||||
defer m.mutex.Unlock()
|
defer m.mutex.Unlock()
|
||||||
|
|
||||||
// Turn module on
|
// Turn module on
|
||||||
m.logger.Println("=============================== Turn on module")
|
m.logger.Println("=============================== Init gpio")
|
||||||
if err := m.onOffPin.Init(); err != nil {
|
if err := m.onOffPin.Init(); err != nil {
|
||||||
return fmt.Errorf("gpio pin init: %w", err)
|
return fmt.Errorf("gpio pin init: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
m.logger.Println("=============================== Search")
|
m.logger.Println("=============================== Search")
|
||||||
// Soft search
|
ports, err := m.searchPort(true)
|
||||||
if err := m.searchPort(true); err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("soft port search: %w", err)
|
return fmt.Errorf("soft port search: %w", err)
|
||||||
}
|
}
|
||||||
// Wide search
|
if len(ports) == 0 {
|
||||||
if m.port == nil {
|
// Wide search
|
||||||
if err := m.searchPort(false); err != nil {
|
ports, err := m.searchPort(true)
|
||||||
return fmt.Errorf("not soft port search: %w", err)
|
if err != nil {
|
||||||
|
return fmt.Errorf("wide port search: %w", err)
|
||||||
|
}
|
||||||
|
if len(ports) == 0 {
|
||||||
|
return fmt.Errorf("no AT ports found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if m.port == nil {
|
if len(ports) == 1 {
|
||||||
return fmt.Errorf("no port is detected")
|
// return fmt.Errorf("only one AT port found")
|
||||||
|
m.logger.Println("!!!!! only one AT port found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !!!!
|
||||||
|
// Internet connection and serial connection on one port is impossible, so:
|
||||||
|
// port[0] is for serial
|
||||||
|
// port[1] is for internet(ppp)
|
||||||
|
m.logger.Println(ports)
|
||||||
|
|
||||||
// Connect
|
// Connect
|
||||||
m.logger.Println("=============================== Connect")
|
m.logger.Println("=============================== Connect")
|
||||||
|
m.port = at.New(m.logger, ports[0], m.baudrate)
|
||||||
if err := m.connect(); err != nil {
|
if err := m.connect(); err != nil {
|
||||||
return fmt.Errorf("connect: %w", err)
|
return fmt.Errorf("connect: %w", err)
|
||||||
}
|
}
|
||||||
@ -113,17 +131,11 @@ func (m *modem) Init() error {
|
|||||||
|
|
||||||
m.logger.Println("=============================== Init submodules")
|
m.logger.Println("=============================== Init submodules")
|
||||||
// m.ic = internet.New(log.New(submodulesLogger, "modem-internet : ", log.LstdFlags), m.port)
|
// m.ic = internet.New(log.New(submodulesLogger, "modem-internet : ", log.LstdFlags), m.port)
|
||||||
// if err := m.ic.Init(); err != nil {
|
// if err := m.ic.Init(ports[1]); err != nil {
|
||||||
// m.logger.Printf("\x1b[38;2;255;0;0mInternet: %s\x1b[38;2;255;255;255m\n", err.Error())
|
// m.logger.Printf("\x1b[38;2;255;0;0mInternet: %s\x1b[38;2;255;255;255m\n", err.Error())
|
||||||
// } else {
|
// } else {
|
||||||
// m.logger.Println("\x1b[38;2;0;255;0mInternet OK\x1b[38;2;255;255;255m")
|
// m.logger.Println("\x1b[38;2;0;255;0mInternet OK\x1b[38;2;255;255;255m")
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// if err := m.ic.Connect(); err != nil {
|
|
||||||
// m.logger.Println("connect to internet: %w", err)
|
|
||||||
// } else {
|
|
||||||
// m.logger.Println("internet connected")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// m.sms = sms.New(log.New(submodulesLogger, "modem-sms : ", log.LstdFlags), m.port)
|
// m.sms = sms.New(log.New(submodulesLogger, "modem-sms : ", log.LstdFlags), m.port)
|
||||||
// if err := m.sms.Init(); err != nil {
|
// if err := m.sms.Init(); err != nil {
|
||||||
@ -176,6 +188,35 @@ func (m *modem) GetData() ModemData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *modem) GetTime() (time.Time, error) {
|
||||||
|
// Make request
|
||||||
|
resp, err := m.port.Send("AT+CCLK?")
|
||||||
|
if err != nil {
|
||||||
|
return time.Time{}, err
|
||||||
|
}
|
||||||
|
if !resp.Check() || !resp.CheckFront("+CCLK: ") {
|
||||||
|
return time.Time{}, fmt.Errorf("CCLK? error response: %s", resp.String())
|
||||||
|
}
|
||||||
|
// Extract time string
|
||||||
|
values := strings.Split(strings.Split(resp.String(), "\n")[0], "\"")
|
||||||
|
if len(values) < 2 {
|
||||||
|
return time.Time{}, fmt.Errorf("invalid values (len): [%s]", values)
|
||||||
|
}
|
||||||
|
timeStr := values[1]
|
||||||
|
if len(timeStr) != len("yy/MM/dd,hh:mm:ss+zz") {
|
||||||
|
return time.Time{}, fmt.Errorf("invalid time string: %s", timeStr)
|
||||||
|
}
|
||||||
|
// Convert time zone
|
||||||
|
timeZoneStr := timeStr[len(timeStr)-2:]
|
||||||
|
timeZone, err := strconv.Atoi(timeZoneStr)
|
||||||
|
if err != nil {
|
||||||
|
return time.Time{}, fmt.Errorf("parse time zone: %w", err)
|
||||||
|
}
|
||||||
|
timeStr = fmt.Sprintf("%s%02d%02d", timeStr[:len(timeStr)-2], timeZone/4, timeZone%4)
|
||||||
|
// Parse to golang time
|
||||||
|
return time.Parse(timeLayout, timeStr)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *modem) PowerOn() error {
|
func (m *modem) PowerOn() error {
|
||||||
m.onOffPin.PowerOn() // DEBUG do not want to wait 30 seconds
|
m.onOffPin.PowerOn() // DEBUG do not want to wait 30 seconds
|
||||||
return nil
|
return nil
|
||||||
@ -205,24 +246,38 @@ func (m *modem) At() at.Port {
|
|||||||
return m.port
|
return m.port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *modem) Ic() internet.Conn {
|
||||||
|
return m.ic
|
||||||
|
}
|
||||||
|
|
||||||
func (m *modem) Close() error { // I can't return error so I log it
|
func (m *modem) Close() error { // I can't return error so I log it
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
defer m.mutex.Unlock()
|
||||||
|
|
||||||
if err := m.sms.Close(); err != nil {
|
// Close submodules
|
||||||
m.logger.Printf("\x1b[38;2;255;0;0mclose sms error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
if m.sms != nil {
|
||||||
|
if err := m.sms.Close(); err != nil {
|
||||||
|
m.logger.Printf("\x1b[38;2;255;0;0mclose sms error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if m.ic != nil {
|
||||||
|
if err := m.ic.Close(); err != nil {
|
||||||
|
m.logger.Printf("\x1b[38;2;255;0;0mclose internet error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if m.gps != nil {
|
||||||
|
if err := m.gps.Close(); err != nil {
|
||||||
|
m.logger.Printf("\x1b[38;2;255;0;0mclose gps error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.port.Close(); err != nil {
|
// Close gpio and serial
|
||||||
m.logger.Printf("\x1b[38;2;255;0;0mclose serial port error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
|
||||||
}
|
|
||||||
if err := m.onOffPin.Close(); err != nil {
|
if err := m.onOffPin.Close(); err != nil {
|
||||||
m.logger.Printf("\x1b[38;2;255;0;0mclose gpio pin error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
m.logger.Printf("\x1b[38;2;255;0;0mclose gpio pin error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
||||||
}
|
}
|
||||||
if err := m.ic.Close(); err != nil {
|
if err := m.port.Close(); err != nil {
|
||||||
m.logger.Printf("\x1b[38;2;255;0;0mclose internet connection error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
m.logger.Printf("\x1b[38;2;255;0;0mclose serial port error: %s\x1b[38;2;255;255;255m\n", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,34 +436,6 @@ func (m *modem) checkPort(portName string) (outErr error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *modem) searchPort(isSoft bool) error {
|
|
||||||
// Get ports
|
|
||||||
ports := []string{"ttyUSB1", "ttyUSB2", "ttyUSB3"}
|
|
||||||
if !isSoft {
|
|
||||||
ps, err := getTtyDevices()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Errorf("get serial devices: %w", err)
|
|
||||||
}
|
|
||||||
ports = ps
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check ports
|
|
||||||
SearchLoop:
|
|
||||||
for _, p := range ports {
|
|
||||||
m.logger.Printf("Checking port %s ...\n", p)
|
|
||||||
|
|
||||||
if err := m.checkPort("/dev/" + p); err != nil {
|
|
||||||
m.logger.Printf("\x1b[38;2;255;0;0mCheck failed: %s\x1b[38;2;255;255;255m\n", err.Error())
|
|
||||||
continue SearchLoop
|
|
||||||
}
|
|
||||||
|
|
||||||
m.logger.Print("Found modem on port: ", p)
|
|
||||||
m.port = at.New(m.logger, "/dev/"+p, m.baudrate)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *modem) ping() error {
|
func (m *modem) ping() error {
|
||||||
resp, err := m.port.Send("AT")
|
resp, err := m.port.Send("AT")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -420,7 +447,36 @@ func (m *modem) ping() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTtyDevices() ([]string, error) {
|
func (m *modem) searchPort(isSoft bool) ([]string, error) {
|
||||||
|
// Get ports
|
||||||
|
ports, err := getTtyPorts(isSoft)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Errorf("get devices: %w", err)
|
||||||
|
}
|
||||||
|
// Check ports
|
||||||
|
return m.getAtPorts(ports)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *modem) getAtPorts(ports []string) ([]string, error) {
|
||||||
|
outPorts := make([]string, 0)
|
||||||
|
for _, p := range ports {
|
||||||
|
m.logger.Printf("Checking port %s ...\n", p)
|
||||||
|
|
||||||
|
if err := m.checkPort("/dev/" + p); err != nil {
|
||||||
|
m.logger.Printf("\x1b[38;2;255;0;0mCheck failed: %s\x1b[38;2;255;255;255m\n", err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
m.logger.Print("Found AT port: ", p)
|
||||||
|
outPorts = append(outPorts, "/dev/"+p)
|
||||||
|
}
|
||||||
|
return outPorts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTtyPorts(isSoft bool) ([]string, error) {
|
||||||
|
if isSoft {
|
||||||
|
return []string{"ttyUSB1", "ttyUSB2", "ttyUSB3"}, nil
|
||||||
|
}
|
||||||
// Get ports
|
// Get ports
|
||||||
/**/
|
/**/
|
||||||
out, err := exec.Command("ls", "--", "/dev/tty[!0-9]*").Output()
|
out, err := exec.Command("ls", "--", "/dev/tty[!0-9]*").Output()
|
||||||
|
@ -41,14 +41,24 @@ func (d *dialer) Init() error {
|
|||||||
return fmt.Errorf("check PIN: %w", err)
|
return fmt.Errorf("check PIN: %w", err)
|
||||||
}
|
}
|
||||||
// Setup prefered message storage
|
// Setup prefered message storage
|
||||||
if err := d.setupMsgSt(); err != nil {
|
// if err := d.setupMsgSt(); err != nil { // Does not use store now
|
||||||
d.logger.Printf("ERROR setup msg storage: %s\n", err.Error())
|
// 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())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check number
|
// Check number
|
||||||
if resp, err := d.port.Send("AT+CNUM"); err != nil || !resp.Check() {
|
if resp, err := d.port.Send("AT+CNUM"); err != nil || !resp.Check() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("AT+CNUM request ")
|
return err
|
||||||
}
|
}
|
||||||
|
return fmt.Errorf("CNUM error response: %s", resp.String())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
70
main.go
70
main.go
@ -9,7 +9,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gitea.unprism.ru/KRBL/sim-modem/api/modem"
|
"gitea.unprism.ru/KRBL/sim-modem/api/modem"
|
||||||
"gitea.unprism.ru/KRBL/sim-modem/api/modem/at"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -17,6 +16,11 @@ func main() {
|
|||||||
|
|
||||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
// Just for logs
|
||||||
|
go func(ctx context.Context) {
|
||||||
|
<-ctx.Done()
|
||||||
|
log.Println("GOT INTERUPT SIGNAL")
|
||||||
|
}(ctx)
|
||||||
|
|
||||||
if err := mainE(ctx); err != nil {
|
if err := mainE(ctx); err != nil {
|
||||||
log.Println("MAIN finished with error:", err.Error())
|
log.Println("MAIN finished with error:", err.Error())
|
||||||
@ -29,25 +33,37 @@ func mainE(ctx context.Context) error {
|
|||||||
m := modem.New(log.New(logger.Writer(), "modem : ", log.LstdFlags))
|
m := modem.New(log.New(logger.Writer(), "modem : ", log.LstdFlags))
|
||||||
|
|
||||||
logger.Println("||||||||||||||||| INIT |||||||||||||||")
|
logger.Println("||||||||||||||||| INIT |||||||||||||||")
|
||||||
if err := m.Init(); err != nil {
|
initLoop:
|
||||||
logger.Println("Init ended with error:", err.Error())
|
for {
|
||||||
logger.Println("Try to turn on")
|
select {
|
||||||
if err := m.PowerOn(); err != nil {
|
case <-ctx.Done():
|
||||||
return err
|
logger.Println("Break init loop")
|
||||||
}
|
return nil
|
||||||
logger.Println("Reinit")
|
default:
|
||||||
if err := m.Init(); err != nil {
|
if err := m.Init(); err != nil {
|
||||||
return err
|
logger.Println("Init ended with error:", err.Error())
|
||||||
|
// logger.Println("Turn on...")
|
||||||
|
// if err := m.PowerOn(); err != nil {
|
||||||
|
// logger.Println("Turn on error:", err.Error())
|
||||||
|
// }
|
||||||
|
continue initLoop
|
||||||
|
}
|
||||||
|
break initLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !m.IsConnected() {
|
if !m.IsConnected() {
|
||||||
logger.Println("AAAAAAAAAAAAAAA Modem is not connected")
|
logger.Println("Modem is not connected")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
logger.Println("||||||||||||||||| CLOSE |||||||||||||||")
|
||||||
|
m.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
// logger.Println("||||||||||||||||| GET INFO |||||||||||||||||")
|
// Connect to internet
|
||||||
// logger.Println(m.Update())
|
// if err := m.Ic().Connect(); err != nil {
|
||||||
// logger.Printf("DATA: %+v\n", m.GetData())
|
// return fmt.Errorf("connect to internet: %w", err)
|
||||||
|
// }
|
||||||
|
|
||||||
logger.Println("||||||||||||||||| SMS |||||||||||||||||")
|
logger.Println("||||||||||||||||| SMS |||||||||||||||||")
|
||||||
Cmd := func(cmd string) {
|
Cmd := func(cmd string) {
|
||||||
@ -56,13 +72,6 @@ func mainE(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
_ = Cmd
|
_ = Cmd
|
||||||
|
|
||||||
var resp at.Resp
|
|
||||||
var err error
|
|
||||||
buf := make([]byte, 256)
|
|
||||||
_ = resp
|
|
||||||
_ = err
|
|
||||||
_ = buf
|
|
||||||
|
|
||||||
// Select ME PMS
|
// Select ME PMS
|
||||||
// logger.Println("SEND SMS")
|
// logger.Println("SEND SMS")
|
||||||
// logger.Println(m.Sms().Send("+79218937173", "CGSG forever!!!"))
|
// logger.Println(m.Sms().Send("+79218937173", "CGSG forever!!!"))
|
||||||
@ -78,17 +87,30 @@ func mainE(ctx context.Context) error {
|
|||||||
// Cmd("AT+CPSI?")
|
// Cmd("AT+CPSI?")
|
||||||
// resp, err = m.At().Send("AT+CNMI=2,2")
|
// resp, err = m.At().Send("AT+CNMI=2,2")
|
||||||
for {
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
logger.Println("Break main loop")
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
// Cmd("AT+CPSI?")
|
||||||
|
// Cmd("AT+CSQ")
|
||||||
|
// Cmd("AT+CCLK?")
|
||||||
|
// logger.Println(m.Gps().GetStatus())
|
||||||
|
// m.Update()
|
||||||
|
// st, _ := m.Gps().GetStatus()
|
||||||
|
// logger.Printf("GPS STATUS: %+v", st)
|
||||||
|
// logger.Printf("GPS DATA: %+v", m.GetData())
|
||||||
|
logger.Println(m.GetTime())
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
}
|
||||||
// Cmd("AT+CSQ")
|
// Cmd("AT+CSQ")
|
||||||
// Cmd("AT+COPS?")
|
// Cmd("AT+COPS?")
|
||||||
|
|
||||||
Cmd("AT+CPSI?")
|
|
||||||
// if err := m.CheckSignal(); err != nil {
|
// if err := m.CheckSignal(); err != nil {
|
||||||
// logger.Println(err)
|
// logger.Println(err)
|
||||||
// } else {
|
// } else {
|
||||||
// logger.Println("AAAAAAAAAAA THERE IS SIGNAL")
|
// logger.Println("AAAAAAAAAAA THERE IS SIGNAL")
|
||||||
// }
|
// }
|
||||||
time.Sleep(500 * time.Millisecond)
|
|
||||||
// readLen, err := m.At().SerialPort().Read(buf)
|
// readLen, err := m.At().SerialPort().Read(buf)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return err
|
// return err
|
||||||
|
Loading…
Reference in New Issue
Block a user