From d8d20e35e5af09c7304435d95a89a7c6ccc5dac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Rudowicz?= Date: Mon, 4 Mar 2024 20:24:13 +0100 Subject: [PATCH] Device name from SATEL with error checking --- get_name.go | 45 +++++++++++++++++++++++++++++++++++++++++---- get_name_test.go | 11 ++++++++++- satel.go | 39 --------------------------------------- 3 files changed, 51 insertions(+), 44 deletions(-) diff --git a/get_name.go b/get_name.go index ad13e94..361a890 100644 --- a/get_name.go +++ b/get_name.go @@ -1,6 +1,7 @@ package satel import ( + "errors" "strings" "golang.org/x/text/encoding/charmap" @@ -30,16 +31,52 @@ type NameEvent struct { DevName string } -func makeNameEvent(bytes []byte) NameEvent { +func makeNameEvent(bytes []byte) (*NameEvent, error) { + if len(bytes) < 19 { + return nil, errors.New("Received data too short") + } cp1250dec := charmap.Windows1250.NewDecoder() name, err := cp1250dec.String(string(bytes[3:19])) if err != nil { - name = "CP1250 DECODE ERROR" + return nil, err } - return NameEvent{ + return &NameEvent{ DevType: DeviceType(bytes[0]), DevNumber: bytes[1], DevTypeFunction: bytes[2], DevName: strings.TrimSpace(name), - } + }, nil +} + +type getNameResult struct { + ev *NameEvent + err error +} + +func (s *Satel) GetName(devType DeviceType, devIndex byte) (*NameEvent, error) { + resultChan := make(chan getNameResult) + + s.commandQueue <- func() { + err := s.sendCmd(0xEE, byte(devType), devIndex) + if err != nil { + resultChan <- getNameResult{nil, errors.New("Could not send Satel read device name")} + } + + var bytes = <-s.rawEvents + if len(bytes) < (1 + 19 + 2) { + resultChan <- getNameResult{nil, errors.New("Received data too short")} + } + cmd := bytes[0] + bytes = bytes[1 : len(bytes)-2] + if cmd == 0xEF { + resultChan <- getNameResult{nil, errors.New("Did not receive a name")} + } else if cmd == 0xEE { + name, err := makeNameEvent(bytes) + resultChan <- getNameResult{name, err} + } else { + resultChan <- getNameResult{nil, errors.New("Received unexpected result instead of a name")} + } + } + nameResult := <-resultChan + return nameResult.ev, nameResult.err } diff --git a/get_name_test.go b/get_name_test.go index f961f07..ef32e66 100644 --- a/get_name_test.go +++ b/get_name_test.go @@ -7,10 +7,19 @@ import ( func TestMakeNameEvent(t *testing.T) { assert := assert.New(t) + name, err := makeNameEvent([]byte{01, 02, 03, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0xFF}) assert.Equal(NameEvent{ DevType: DeviceType(1), DevNumber: 2, DevTypeFunction: 3, DevName: "0123456789ABCDEF", - }, makeNameEvent([]byte{01, 02, 03, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0xFF})) + }, *name) + assert.NoError(err) +} + +func TestMakeNameEvent_tooShort(t *testing.T) { + assert := assert.New(t) + name, err := makeNameEvent([]byte{01, 02, 03, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}) + assert.Nil(name) + assert.Error(err) } diff --git a/satel.go b/satel.go index da9f7e3..eadc443 100644 --- a/satel.go +++ b/satel.go @@ -3,7 +3,6 @@ package satel import ( "bufio" "errors" - "fmt" "net" "sync" "time" @@ -105,44 +104,6 @@ func (s *Satel) SetOutput(code string, index int, value bool) error { return s.sendCmd(bytes...) } -func (s *Satel) GetName(devType DeviceType, devIndex byte) NameEvent { - resultChan := make(chan NameEvent) - - s.commandQueue <- func() { - err := s.sendCmd(0xEE, byte(devType), devIndex) - if err != nil { - resultChan <- NameEvent{ - DevType: DeviceType(devType), - DevNumber: devIndex, - DevTypeFunction: 0, - DevName: fmt.Sprint("ERROR RETRIEVING NAME ", devType, devIndex), - } - } - - var bytes = <-s.rawEvents - cmd := bytes[0] - bytes = bytes[1 : len(bytes)-2] - if cmd == 0xEF { - resultChan <- NameEvent{ - DevType: DeviceType(devType), - DevNumber: devIndex, - DevTypeFunction: 0, - DevName: fmt.Sprint("NO NAME ", devType, devIndex), - } - } else if cmd == 0xEE { - resultChan <- makeNameEvent(bytes) - } else { - resultChan <- NameEvent{ - DevType: DeviceType(devType), - DevNumber: devIndex, - DevTypeFunction: 0, - DevName: fmt.Sprint("ERROR GETTING NAME ", devType, devIndex), - } - } - } - return <-resultChan -} - func prepareCommand(code string, cmd byte, data ...byte) []byte { bytes := append([]byte{cmd}, transformCode(code)...) return append(bytes, data...)