Skip to content

Commit

Permalink
hotfix: Fix timeout problem on command with long respond time
Browse files Browse the repository at this point in the history
  • Loading branch information
selengalp committed Dec 14, 2023
1 parent 0fddd1c commit 235c4f0
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 26 deletions.
65 changes: 39 additions & 26 deletions atcom.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Copyright (c) 2023 Sixfab Inc.
package atcom

import (
"bufio"
"context"
"errors"
"strings"
Expand Down Expand Up @@ -75,8 +74,7 @@ func SendAT(command string, args map[string]interface{}) ([]string, error) {
return nil, err
}

scanner := bufio.NewScanner(serialPort)
response := make([]string, 0)
data := make([]string, 0)
timeoutDuration := time.Duration(timeout) * time.Second

found := make(chan error)
Expand All @@ -86,48 +84,63 @@ func SendAT(command string, args map[string]interface{}) ([]string, error) {
defer cancelScan()

go func(ctx context.Context) {
response := ""
buf := make([]byte, 1024)

for {
if !scanner.Scan() {
time.Sleep(time.Millisecond * 5)
n, err := serialPort.Read(buf)
if err != nil {
if err.Error() == "EOF" {
continue
}
found <- err
return
}
line := scanner.Text()
line = strings.TrimSpace(line)
line = strings.Trim(line, "\r")
line = strings.Trim(line, "\n")

if line != "" {
response = append(response, line)
if n > 0 {
response += string(buf[:n])
}

if line == "OK" {
// make response string to check desired and fault
data := ""
for _, word := range response {
if word != "OK" {
data += word
if strings.Contains(response, "\r\nOK\r\n") {
lines := strings.Split(response, "\r\n")

for _, line := range lines {
line = strings.TrimSpace(line)
line = strings.Trim(line, "\r")
line = strings.Trim(line, "\n")

if line != "" {
data = append(data, line)
}

if line == "OK" {
break
}
}

// check desired and fault existed in response
if desired != nil || fault != nil {
for _, desiredStr := range desired {
if strings.Contains(data, desiredStr) {
if strings.Contains(response, desiredStr) {
found <- nil
return
}
}

for _, faultStr := range fault {
if strings.Contains(data, faultStr) {
found <- errors.New("faulty response detected")
return
for _, faultStr := range fault {
if strings.Contains(response, faultStr) {
found <- errors.New("faulty response detected")
return
}
}
}
} else {
found <- nil
return
}
} else if line == "ERROR" || strings.Contains(line, "+CME ERROR") {

found <- nil
return
} else if strings.Contains(response, "\r\nERROR\r\n") {
found <- errors.New("modem error")
return
}
Expand All @@ -139,10 +152,10 @@ func SendAT(command string, args map[string]interface{}) ([]string, error) {
for {
select {
case err := <-found:
return response, err
return data, err
case <-timeoutCh:
cancelScan()
return response, errors.New("timeout")
return data, errors.New("timeout")
}
}
}
46 changes: 46 additions & 0 deletions examples/test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package main

import (
"fmt"

at "github.com/sixfab/atcomv2"
)

func main() {

port, err := at.DecidePort()

if err != nil {
fmt.Println(err)
}

args := map[string]interface{}{
"port": port["port"],
"baud": 115200,
"lineEnd": true,
"timeout": 5,
}

response, err := at.SendAT("ATE1", args)
fmt.Println(response, err)

response1, err := at.SendAT("AT+CGDCONT?", args)
fmt.Println(response1, err)

response2, err := at.SendAT("AT+COPS?", args)
fmt.Println(response2, err)

// response3, err := at.SendAT("AT#ECMD=0", args)
// fmt.Println(response3, err)

// response4, err := at.SendAT("AT#ECM=1,0", args)
// fmt.Println(response4, err)

// response5, err := at.SendAT("AT#ECM?", args)
// fmt.Println(response5, err)

// command that takes very long time to respond
// response6, err := at.SendAT("AT+COPS=?", args)
// fmt.Println(response6, err)

}

0 comments on commit 235c4f0

Please sign in to comment.