diff --git a/go.mod b/go.mod index d15a018..5568f3c 100644 --- a/go.mod +++ b/go.mod @@ -3,24 +3,20 @@ module github.com/kschamplin/gotelem go 1.20 require ( + github.com/jmoiron/sqlx v1.3.5 + github.com/mattn/go-sqlite3 v1.14.16 + github.com/tinylib/msgp v1.1.8 github.com/urfave/cli/v2 v2.25.1 + go.bug.st/serial v1.5.0 + golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 golang.org/x/sys v0.7.0 ) require ( github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/creack/goselect v0.1.2 // indirect - github.com/jmoiron/sqlx v1.3.5 // indirect - github.com/mattn/go-sqlite3 v1.14.16 // indirect github.com/philhofer/fwd v1.1.2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/tinylib/msgp v1.1.8 // indirect + github.com/stretchr/testify v1.8.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - go.bug.st/serial v1.5.0 // indirect - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect - golang.org/x/mod v0.10.0 // indirect - golang.org/x/tools v0.8.0 // indirect ) diff --git a/go.sum b/go.sum index 472bd42..0613206 100644 --- a/go.sum +++ b/go.sum @@ -2,17 +2,29 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHH github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0= github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw= @@ -22,20 +34,12 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsr github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.bug.st/serial v1.5.0 h1:ThuUkHpOEmCVXxGEfpoExjQCS2WBVV4ZcUKVYInM9T4= go.bug.st/serial v1.5.0/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -62,6 +66,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= -golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/xbee/api_frame.go b/internal/xbee/api_frame.go index 96baa6e..d3ac97b 100644 --- a/internal/xbee/api_frame.go +++ b/internal/xbee/api_frame.go @@ -108,6 +108,8 @@ func xbeeFrameSplit(data []byte, atEOF bool) (advance int, token []byte, err err // we add 4 since start delimiter (1) + length (2) + checksum (1). // the length inside the packet represents the frame data only. if len(data[startIdx:]) < 3 { + // since we don't have enough bytes to get the length, instead we + // will discard all data before the start index return startIdx, nil, nil } // FIXME: add bounds checking! this can panic. @@ -125,6 +127,8 @@ func xbeeFrameSplit(data []byte, atEOF bool) (advance int, token []byte, err err return len(data), nil, nil } +// parseFrame takes a framed packet and returns the contents after checking the +// checksum and start delimiter. func parseFrame(frame []byte) ([]byte, error) { if frame[0] != 0x7E { return nil, errors.New("incorrect start delimiter") @@ -139,6 +143,7 @@ func parseFrame(frame []byte) ([]byte, error) { // stackup // low level readwriter (serial or IP socket) // XBee library layer (frame encoding/decoding to/from structs) +// AT command layer (for setup/control) // xbee conn-like layer (ReadWriter + custom control functions) // application marshalling format (msgpack or json or gob) // application diff --git a/internal/xbee/session.go b/internal/xbee/session.go index 8b524f1..fc1bdda 100644 --- a/internal/xbee/session.go +++ b/internal/xbee/session.go @@ -7,7 +7,7 @@ import ( "sync" "go.bug.st/serial" - "go.uber.org/zap" + "golang.org/x/exp/slog" ) // todo: make transport-agnostic (serial port or TCP/IP) @@ -31,7 +31,7 @@ type Session interface { type SerialSession struct { port serial.Port ct connTrack - log *zap.SugaredLogger + slog.Logger // todo: add queuing structures here for reliable transport and tracking. // this buffer is used for storing data that must be read at some point. rxBuf *bufio.ReadWriter @@ -57,12 +57,6 @@ func NewSerialXBee(portName string, mode *serial.Mode) (*SerialSession, error) { // will write to the buffer when new Rx packets come in, and we can read out from application code. sess.rxBuf = bufio.NewReadWriter(bufio.NewReader(rd), bufio.NewWriter(wr)) - logger, err := zap.NewDevelopment() - if err != nil { - return sess, err - } - sess.log = logger.Sugar() - // start the rx handler in the background. we close it later by closing the serial port. go sess.rxHandler() @@ -86,7 +80,7 @@ func (sess *SerialSession) rxHandler() { // data is a frame payload - not a full frame. data, err := parseFrame(scan.Bytes()) if err != nil { - sess.log.Warnw("error parsing frame", "error", err, "data", data) + sess.Logger.Warn("error parsing frame", "error", err, "data", data) continue } // data is good, lets parse the frame - using the first byte as the identifier. @@ -97,13 +91,13 @@ func (sess *SerialSession) rxHandler() { //TODO: if we have multiple sources, we need to track them here. frame, err := ParseRxFrame(data) if err != nil { - sess.log.Warnw("error parsing rx packet", "error", err, "data", data) + sess.Logger.Warn("error parsing rx packet", "error", err, "data", data) break //continue? } // take the data and write it to our internal rx packet buffer. _, err = sess.rxBuf.Write(frame.Payload) if err != nil { - sess.log.Warnw("error writing data", "error", err, "payload", frame.Payload) + sess.Logger.Warn("error writing data", "error", err, "payload", frame.Payload) } // the "callback"-style handler. Any received packet with a frame ID should @@ -116,12 +110,12 @@ func (sess *SerialSession) rxHandler() { err := sess.ct.ClearMark(idx, data) if err != nil { // we got a rogue packet lol - sess.log.Warnw("rogue frame ID", "id", idx, "error", err) + sess.Logger.Warn("rogue frame ID", "id", idx, "error", err) } default: // we don't know what to do with it. - sess.log.Infow("unhandled packet type", "type", data[0], "id", data[1]) + sess.Logger.Info("unhandled packet type", "type", data[0], "id", data[1]) } @@ -240,3 +234,7 @@ func (sess *SerialSession) GetStatus() { func (sess *SerialSession) Close() error { return sess.port.Close() } + +func (sess *SerialSession) DiscoverNodes() { + +}