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 GetStatus() (Status, 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("get GPS info: error response: %s", resp) } 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) GetData() Data { return g.data } func (g *gps) Close() error { 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("get GPS mode: error response: %s", resp) } 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("set GPS mode: %w", err) } if !resp.Check() { return fmt.Errorf("set GPS mode: error response: %s", resp) } return nil }