105 lines
2.0 KiB
Go
105 lines
2.0 KiB
Go
package gps
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"strings"
|
|
|
|
"github.com/CGSG-2021-AE4/modem-test/api/modem/at"
|
|
)
|
|
|
|
type gps struct {
|
|
logger *log.Logger
|
|
port at.Port
|
|
data Data
|
|
}
|
|
|
|
type Gps interface {
|
|
Init() error
|
|
Update() error
|
|
GetData() Data
|
|
CheckStatus() error
|
|
io.Closer
|
|
}
|
|
|
|
func New(logger *log.Logger, port at.Port) Gps {
|
|
return &gps{
|
|
logger: logger,
|
|
port: port,
|
|
}
|
|
}
|
|
|
|
func (g *gps) Init() error {
|
|
if !g.port.IsConnected() {
|
|
return fmt.Errorf("at port is not connected")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (g *gps) Update() error {
|
|
if err := g.switchGpsMode(true); err != nil {
|
|
return fmt.Errorf("try to GPS mode: %w", err)
|
|
}
|
|
defer g.switchGpsMode(false)
|
|
|
|
resp, err := g.port.Send("AT+CGPSINFO")
|
|
if err != nil {
|
|
return fmt.Errorf("receive GPS data: %w", err)
|
|
}
|
|
if !resp.Check() {
|
|
return fmt.Errorf("error response")
|
|
}
|
|
if err := g.data.decode(strings.Split(strings.Replace(resp.RmFront("+CGPSINFO:").String(), "\r", "", -1), "\n")[0]); err != nil {
|
|
return fmt.Errorf("decode: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (g *gps) switchGpsMode(on bool) error {
|
|
onStr := "0"
|
|
if on {
|
|
onStr = "1"
|
|
}
|
|
|
|
// Reset input
|
|
if err := g.port.SerialPort().ResetInputBuffer(); err != nil {
|
|
return fmt.Errorf("reset input buffer: %w", err)
|
|
}
|
|
// Reset output
|
|
if err := g.port.SerialPort().ResetOutputBuffer(); err != nil {
|
|
return fmt.Errorf("reset output buffer: %w", err)
|
|
}
|
|
|
|
// Check gps mode status
|
|
resp, err := g.port.Send("AT+CGPS?")
|
|
if err != nil {
|
|
return fmt.Errorf("make at ask: %w", err)
|
|
}
|
|
if !resp.Check() {
|
|
return fmt.Errorf("error response")
|
|
}
|
|
ans := strings.Replace(strings.Split(strings.Split(resp.RmFront("+CGPS:").String(), "\n")[0], ",")[0], " ", "", -1)
|
|
if ans == onStr {
|
|
return nil
|
|
}
|
|
|
|
// Modem is not in GPS mode
|
|
resp, err = g.port.Send("AT+CGPS=" + onStr)
|
|
if err != nil {
|
|
return fmt.Errorf("try to switch to gps: %w", err)
|
|
}
|
|
if !resp.Check() {
|
|
return fmt.Errorf("switch tp GPS failed")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (g *gps) GetData() Data {
|
|
return g.data
|
|
}
|
|
|
|
func (g *gps) Close() error {
|
|
return nil
|
|
}
|