Changed at requests.
This commit is contained in:
parent
dbb4fc5939
commit
6b8284ee47
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
out/
|
||||
Makefile
|
||||
go.sum
|
||||
.git/
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
17
api/modem/at/response.go
Normal 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)
|
||||
}
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user