missing error handling added

This commit is contained in:
Torsten Harenberg
2025-02-28 14:59:31 +01:00
parent 49058adbfd
commit 4ed3ce9b10
7 changed files with 265 additions and 147 deletions

86
ptc.go
View File

@@ -118,7 +118,7 @@ func writeDebug(message string, level int) {
return
}
// OpenModem: Initialise the pactor modem and all variables. Switch the modem into hostmode.
// OpenModem Initialise the pactor modem and all variables. Switch the modem into hostmode.
//
// Will abort if modem reports failed link setup, Close() is called or timeout
// has occured (90 seconds)
@@ -208,7 +208,7 @@ func (p *Modem) init() (err error) {
}
if len(ans) < 2 {
return errors.New("Modem does not react to Quit command. Please re-power your modem")
return errors.New("modem does not react to Quit command. Please re-power your modem")
}
// Check if we can determine the modem's type
@@ -288,7 +288,12 @@ func (p *Modem) runInitScript(initScript string) error {
if err != nil {
return err
}
defer file.Close()
defer func() {
err := file.Close()
if err != nil {
writeDebug(err.Error(), 0)
}
}()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
@@ -386,14 +391,20 @@ func (p *Modem) modemThread() {
writeDebug("response: "+string(res)+"\n"+hex.Dump(res), 3)
switch c {
case PactorChannel:
s.Data.Response.Enqueue(res)
err := s.Data.Response.Enqueue(res)
if err != nil {
writeDebug(err.Error(), 0)
}
writeDebug("Written to sendbuf", 3)
case 254: //Status update
p.chanbusy = int(res[0])&112 == 112 // See PTC-IIIusb manual "STATUS" command
writeDebug("PACTOR state: "+strconv.FormatInt(int64(res[0]), 2), 2)
case TRXControlChannel:
//if !bytes.Equal(res, trxcmd) {
s.FromTRX.Enqueue(res)
err := s.FromTRX.Enqueue(res)
if err != nil {
writeDebug(err.Error(), 0)
}
writeDebug("TRX CMD answer:\n"+hexdump.Dump(res), 1)
//}
default:
@@ -448,19 +459,20 @@ func (p *Modem) stophostmode() {
n, _, err := p.read(100)
if err != nil {
log.Fatal(err)
break
}
if n == 0 {
break
}
}
p.write("\rRESTART\r")
err = p.write("\rRESTART\r")
if err != nil {
writeDebug(err.Error(), 0)
}
time.Sleep(1000 * time.Millisecond)
for {
n, a, err := p.read(100)
if err != nil {
log.Fatal(err)
break
}
if n == 0 {
break
@@ -525,11 +537,6 @@ func (p *Modem) close() (err error) {
return nil
}
// Set specified flag (channel)
func setFlag(flag chan struct{}) {
flag <- struct{}{}
}
// Get number of frames not yet transmitted by the modem
func (p *Modem) getNumFramesNotTransmitted() int {
//return p.channelState.c
@@ -542,7 +549,7 @@ func (p *Modem) getNumFrameNotAck() int {
return 0
}
// Check if serial device is still available (e.g still connected)
// Check if serial device is still available (e.g. still connected)
func (p *Modem) checkSerialDevice() (err error) {
if _, err := os.Stat(p.devicePath); os.IsNotExist(err) {
return fmt.Errorf("ERROR: Device %s does not exist", p.devicePath)
@@ -578,7 +585,7 @@ func (p *Modem) getChannelsWithOutput() (channels []int, err error) {
// Currently, only connection information (payload) messages are passed on
func (p *Modem) checkResponse(resp string, ch int) (n int, data []byte, err error) {
if len(resp) < 3 {
return 0, nil, fmt.Errorf("No data")
return 0, nil, fmt.Errorf("no data")
}
head := []byte(resp[:3])
@@ -587,11 +594,11 @@ func (p *Modem) checkResponse(resp string, ch int) (n int, data []byte, err erro
pl := len(payload)
if int(head[0]) != ch {
writeDebug("WARNING: Returned data does not match polled channel\n"+hex.Dump([]byte(resp)), 1)
return 0, nil, fmt.Errorf("Channel missmatch")
return 0, nil, fmt.Errorf("channel missmatch")
}
if int(head[1]) == 1 { //sucess,message follows
writeDebug(fmt.Sprintf("*** SUCCESS on channel %d: %s", ch, string(payload)), 1)
if ch == NMEAChannel && s.GPSdMode {
if ch == NMEAChannel && s.Userconfig.GPSdAddress != "" {
if s.GPSStream.GetLen() == 0 {
s.GPSStream.Enqueue("$" + string(bytes.Trim(payload, "\x00"))) //need to remove the trailing NULL byte
}
@@ -611,7 +618,7 @@ func (p *Modem) checkResponse(resp string, ch int) (n int, data []byte, err erro
s.Command.Response.Enqueue(fmt.Sprintf("%s\n", payload))
}
writeDebug("Message from Modem: "+string(payload), 1)
return 0, nil, fmt.Errorf("Not a data response")
return 0, nil, fmt.Errorf("not a data response")
}
if int(head[1]) == 3 { //Link status
if !s.VARAMode {
@@ -648,7 +655,7 @@ func (p *Modem) checkResponse(resp string, ch int) (n int, data []byte, err erro
//p.channelState.f = 0
return 0, nil, nil
}
return 0, nil, fmt.Errorf("Link data")
return 0, nil, fmt.Errorf("link data")
}
if length != pl {
writeDebug("WARNING: Data length "+strconv.Itoa(pl)+" does not match stated amount "+strconv.Itoa(length)+". After "+strconv.Itoa(p.goodChunks)+" good chunks.", 1)
@@ -711,7 +718,7 @@ func (p *Modem) writeAndGetResponse(msg string, ch int, isCommand bool, chunkSiz
}
time.Sleep(50 * time.Millisecond)
writeDebug("Decode WA8DED", 4)
buf := []byte{}
var buf []byte
valid := false
for valid == false {
@@ -728,7 +735,7 @@ func (p *Modem) writeAndGetResponse(msg string, ch int, isCommand bool, chunkSiz
if err != nil {
writeDebug("ERROR at _read: "+error.Error(err), 1)
}
writeDebug("Len: "+strconv.Itoa(len(buf))+"State: "+string(hex.Dump(buf)+"\n"), 4)
writeDebug("Len: "+strconv.Itoa(len(buf))+" State: "+hex.Dump(buf)+"\n", 4)
if br > 0 {
//we got some data
buf = append(buf, b...)
@@ -780,15 +787,10 @@ func (p *Modem) Busy() bool {
// Although these functions are small, I prefer to keep their functionality
// separate. They follow the steps in the SCS documentation
// printhex: helper function: de-hexlify and write to debug channel
func printhex(s string) {
t, _ := hex.DecodeString(s)
writeDebug(string(t), 3)
}
/*
// unstuff: helper function: "unstuff" a string
func unstuff(s string) string {
//Expect: the string contains aa aa at the beginning, that should NOT be
//Expect: the string contains "aa aa" at the beginning, that should NOT be
//stuffed
n, _ := hex.DecodeString(s[4:])
n = bytes.Replace(n, []byte{170, 0}, []byte{170}, -1)
@@ -797,14 +799,16 @@ func unstuff(s string) string {
re := hex.EncodeToString(r)
return re
}
*/
/*
// stuff: helper function: "stuff" a string: replaces every #170 with #170#0
func stuff(s string) string {
//Expect: the string contains aa aa at the beginning, that should NOT be
//Expect: the string contains "aa aa" at the beginning, that should NOT be
//stuffed
n, err := hex.DecodeString(s[4:])
if err != nil {
writeDebug("ERROR in Stuff: "+err.Error()+"\n"+string(hex.Dump([]byte(s))), 1)
writeDebug("ERROR in Stuff: "+err.Error()+"\n"+hex.Dump([]byte(s)), 1)
}
n = bytes.Replace(n, []byte{170}, []byte{170, 0}, -1)
@@ -813,22 +817,26 @@ func stuff(s string) string {
re := hex.EncodeToString(r)
return re
}
*/
/*
// checksum: helper function: calculates the CCITT-CRC16 checksum
func checksum(s string) uint16 {
tochecksum, _ := hex.DecodeString(s[4:])
chksum := bits.ReverseBytes16(crc16.ChecksumCCITT([]byte(tochecksum)))
chksum := bits.ReverseBytes16(crc16.ChecksumCCITT(tochecksum))
return chksum
}
*/
// checkcrc: helper fuction: check the checksum by comparing
func checkcrc(s []byte) bool {
tochecksum := s[2 : len(s)-2]
chksum := bits.ReverseBytes16(crc16.ChecksumCCITT(tochecksum))
pksum := s[len(s)-2:]
return (binary.BigEndian.Uint16(pksum) == chksum)
return binary.BigEndian.Uint16(pksum) == chksum
}
/*
// docrc: super helper fuction: convert an ordinary WA8DED message into a CRC-Hostmode message
func docrc(msg string) string {
// step 1: add a #170170
@@ -839,8 +847,8 @@ func docrc(msg string) string {
// step 3: add "stuff" bytes
msg = stuff(msg)
return msg
}
*/
// writeChannel: Write channel to serial connection (NOT thread safe)- If used, make sure to mutex!
func (p *Modem) writeChannel(msg string, ch int, isCommand bool) error {
@@ -861,7 +869,7 @@ func (p *Modem) writeChannel(msg string, ch int, isCommand bool) error {
d = byte(0x81)
}
var o []byte = []byte{170, 170, byte(ch), byte(d), byte((len(msg) - 1))}
o := []byte{170, 170, byte(ch), d, byte(len(msg) - 1)}
o = append(o, []byte(msg)...)
cksum := bits.ReverseBytes16(crc16.ChecksumCCITT(o[2:]))
cksumb := make([]byte, 2)
@@ -913,7 +921,10 @@ func (p *Modem) read(readsize int) (int, []byte, error) {
}
buf := make([]byte, chunkSize)
if strings.HasPrefix(p.devicePath, "tcp://") {
p.tcpdevice.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
err := p.tcpdevice.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
if err != nil {
writeDebug(err.Error(), 0)
}
n, err := p.tcpdevice.Read(buf)
if err != nil {
writeDebug("Error received during read: "+err.Error(), 1)
@@ -928,7 +939,10 @@ func (p *Modem) read(readsize int) (int, []byte, error) {
p.mux.device.Lock()
defer p.mux.device.Unlock()
p.device.SetReadTimeout(100) // 100 ms
err := p.device.SetReadTimeout(100) // 100 ms
if err != nil {
writeDebug(err.Error(), 0)
}
n, err := p.device.Read(buf)
if err != nil {
writeDebug("Error received during read: "+err.Error(), 1)