Changed at requests.

This commit is contained in:
Andrey Egorov 2024-07-23 12:22:53 +03:00
parent dbb4fc5939
commit 6b8284ee47
5 changed files with 90 additions and 100 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
out/
Makefile
go.sum
.git/

View File

@ -1,9 +1,9 @@
FROM golang:1.22.5
WORKDIR /app
COPY go.mod go.sum ./
COPY ./ ./
RUN go mod download
COPY *.go ./
RUN CGO_ENABLED=0 GOOS=linux go build -o /modem-test

View File

@ -3,7 +3,6 @@ package at
import (
"fmt"
"log"
"strings"
"time"
"go.bug.st/serial"
@ -15,25 +14,6 @@ const (
InputBufSize = 128
)
// Command types
type CmdType byte
// Command types base on request/answer semantic:
const (
CmdTest CmdType = iota
// AT\r\n
// OK
CmdCheck
// AT+<CMD>\r\n
// OK
CmdGet
// AT+<CMD>\r\n
// +<CMD>: <ANS>
CmdQuestion
// AT+<CMD>?\r\n
// +<CMD>: <ANS>
)
type atPort struct {
baudrate int
portName string
@ -42,12 +22,14 @@ type atPort struct {
}
type Port interface {
GetName() string
GetSerialPort() serial.Port // For extra need
Connect() error
Disconnect() error
Request(cmdType CmdType, cmd string) (string, error)
GetName() string
IsConnected() bool
GetSerialPort() serial.Port // For extra need
Send(cmd string) (Resp, error)
}
func New(portName string, baudrate int) Port {
@ -58,6 +40,14 @@ func New(portName string, baudrate int) Port {
}
}
func (p *atPort) GetName() string {
return p.portName
}
func (p *atPort) GetSerialPort() serial.Port {
return p.port
}
func (p *atPort) Connect() error {
log.Println("Connecting to", p.portName, "...")
s, err := serial.Open(p.portName, &serial.Mode{BaudRate: p.baudrate})
@ -83,6 +73,10 @@ func (p *atPort) Disconnect() error {
return nil
}
func (p *atPort) IsConnected() bool {
return p.port != nil
}
// Low level write/read function
func (p *atPort) makeReq(msg string) (string, error) {
// Write
@ -100,59 +94,16 @@ func (p *atPort) makeReq(msg string) (string, error) {
return string(p.inputBuf[:readLen]), nil
}
func (p *atPort) Request(cmdType CmdType, cmd string) (outStr string, outErr error) {
defer func() {
if outErr != nil {
return
}
log.Println("GOT:", outStr, "BYTE:", []byte(outStr))
}()
msg := "AT"
// Make command
// By default it just will be AT check cmd
switch cmdType {
case CmdGet, CmdCheck:
msg += cmd
case CmdQuestion:
msg += cmd + "?"
}
msg += "\r\n"
rawResp, err := p.makeReq(msg)
log.Println("Got")
func (p *atPort) Send(cmd string) (Resp, error) {
cmd += "\r\n"
rawResp, err := p.makeReq(cmd)
if err != nil {
return "", fmt.Errorf("make at request: %w", err)
return RespNil, fmt.Errorf("make request: %w", err)
}
if len(rawResp) == 0 {
return "", fmt.Errorf("read nothing")
if len(rawResp) <= 4 {
return RespNil, fmt.Errorf("read too small msg: %d byte", len(rawResp))
}
resp := rawResp[2 : len(rawResp)-2] // Cut \r\n
switch cmdType {
case CmdTest, CmdCheck:
// Check and test cmds do not suppose anything but OK
if len(resp) >= 2 && resp[:2] == "OK" {
return "", nil
}
return "", fmt.Errorf("connection lost")
case CmdGet, CmdQuestion:
checkL := len(cmd) + 1
if len(resp) >= checkL && resp[:checkL] != "+"+cmd {
return "", fmt.Errorf("connetion lost")
}
return strings.Split(resp, ":")[1], nil
}
return "", fmt.Errorf("undefined command type")
}
func (p *atPort) GetName() string {
return p.portName
}
func (p *atPort) IsConnected() bool {
return p.port != nil
}
func (p *atPort) GetSerialPort() serial.Port {
return p.port
return Resp(resp), nil
}

17
api/modem/at/response.go Normal file
View File

@ -0,0 +1,17 @@
package at
type Resp string
const RespNil = Resp("")
func (resp Resp) Check() bool {
return len(resp) >= 2 && resp[len(resp)-2:] == "OK"
}
func (resp Resp) RmFront(str string) Resp {
return Resp(string(resp)[len(str):])
}
func (resp Resp) Str() string {
return string(resp)
}

View File

@ -76,8 +76,6 @@ func (m *modem) Init() error {
return fmt.Errorf("soft port search: %w", err)
}
return nil
// Common search
if m.port == nil {
if err := m.SearchPort(false); err != nil {
@ -121,7 +119,16 @@ func (m *modem) checkPort(portName string) error {
}
// Check model
model, err := m.port.Request(at.CmdGet, "CGMM")
log.Println("Check model...")
resp, err := m.port.Send("AT+CGMM")
if err != nil {
return fmt.Errorf("get model: %w", err)
}
if !resp.Check() {
return fmt.Errorf("error response: %s", resp)
}
model := resp.RmFront("+CGMM:").String()
if err != nil {
return fmt.Errorf("get model: %w", err)
}
@ -168,8 +175,14 @@ func (m *modem) Connect() error {
}
func (m *modem) Ping() error {
_, err := m.port.Request(at.CmdTest, "")
return err
resp, err := m.port.Send("AT")
if err != nil {
return err
}
if resp.Check() {
return fmt.Errorf("connection lost")
}
return nil
}
func (m *modem) SwitchToGpsMode() error {
@ -180,20 +193,27 @@ func (m *modem) SwitchToGpsMode() error {
}
// Check gps mode status
ans, err := m.port.Request(at.CmdQuestion, "CGPS")
resp, err := m.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.Split(resp.RmFront("+CGPS:").String(), "\n")[0]
if ans == "1" {
log.Println("GPS already enabled")
return nil
}
// Modem is not in GPS mode
_, err = m.port.Request(at.CmdCheck, "CGPS=1")
resp, err = m.port.Send("AT+CGPS=1")
if err != nil {
return fmt.Errorf("try to switch to gps: %w", err)
}
if !resp.Check() {
return fmt.Errorf("switch tp GPS failed")
}
log.Println("GPS mode enabled")
return nil
}
@ -220,31 +240,32 @@ func (m *modem) Update() error {
log.Println("No connection to module")
return nil
}
ans, err := m.port.Request(at.CmdQuestion, "CGPSINFO")
if err != nil {
return fmt.Errorf("check GPS info mode: %w", err)
}
ok := ans == "1"
if !ok {
_, err := m.port.Request(at.CmdCheck, "CGPSINFO")
if err != nil {
return fmt.Errorf("switch to GPS info mode: %w", err)
}
log.Println("switched to GPS mode")
} else {
log.Println("mode in right GPS mode")
}
// ans, err := m.port.Request(at.CmdQuestion, "CGPSINFO")
// if err != nil {
// return fmt.Errorf("check GPS info mode: %w", err)
// }
// ok := ans == "1"
// if !ok {
// _, err := m.port.Request(at.CmdCheck, "CGPSINFO")
// if err != nil {
// return fmt.Errorf("switch to GPS info mode: %w", err)
// }
// log.Println("switched to GPS mode")
// } else {
// log.Println("mode in right GPS mode")
// }
// Update
log.Println("Receiving GPS data...")
resp, err := m.port.Request(at.CmdGet, "GPSINFO")
resp, err := m.port.Send("AT+GPSINFO")
if err != nil {
return fmt.Errorf("receive GPS data: %w", err)
}
if !resp.Check() {
return fmt.Errorf("error response")
}
log.Println("Decoding data...")
coordinates := strings.Split(resp, ",")
coordinates := strings.Split(strings.Split(resp.RmFront("+CGPSINFO:").String(), "\n")[0], ",")
m.gpsInfo.Latitude, err = strconv.ParseFloat(coordinates[0], 64)
if err != nil {