From 6b9a64bd4a35615075070c2b9db6de76c5c3673d Mon Sep 17 00:00:00 2001 From: andig Date: Wed, 3 Jul 2019 11:28:33 +0200 Subject: [PATCH 1/2] Correct Eui48 length to 8 bytes --- impl/point.go | 14 +++++++++----- sunspec.go | 2 +- typelen/lengths.go | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/impl/point.go b/impl/point.go index 58a3681..d312e9c 100644 --- a/impl/point.go +++ b/impl/point.go @@ -4,13 +4,14 @@ import ( "encoding/binary" "errors" "fmt" - "github.com/crabmusket/gosunspec" + "math" + "strconv" + + sunspec "github.com/crabmusket/gosunspec" "github.com/crabmusket/gosunspec/smdx" "github.com/crabmusket/gosunspec/spi" "github.com/crabmusket/gosunspec/typelabel" "github.com/crabmusket/gosunspec/typelen" - "math" - "strconv" ) var ( @@ -549,7 +550,9 @@ func (p *point) MarshalXML() string { return string(buf) case typelabel.Eui48: buf := []byte{} - for x, b := range p.Eui48() { + eui48 := p.Eui48() + // first word is unused - ignore + for x, b := range eui48[2:] { if x != 0 { buf = append(buf, ':') } @@ -635,7 +638,8 @@ func (p *point) UnmarshalXML(s string) error { } case typelabel.Eui48: var buf sunspec.Eui48 - if _, err := fmt.Sscanf(s, "%02x:%02x:%02x:%02x:%02x:%02x", &buf[0], &buf[1], &buf[2], &buf[3], &buf[4], &buf[5]); err != nil { + // first word is unused - ignore + if _, err := fmt.Sscanf(s, "%02x:%02x:%02x:%02x:%02x:%02x", &buf[2], &buf[3], &buf[4], &buf[5], &buf[6], &buf[7]); err != nil { return err } else { p.SetEui48(buf) diff --git a/sunspec.go b/sunspec.go index 8853303..ffe6357 100644 --- a/sunspec.go +++ b/sunspec.go @@ -66,7 +66,7 @@ type Enum16 uint16 type Enum32 uint32 // An hardware address (like a MAC address) - see https://standards.ieee.org/develop/regauth/tut/eui48.pdf -type Eui48 [6]byte +type Eui48 [8]byte // A 32bit IPv4 address (binary) type Ipaddr [4]byte diff --git a/typelen/lengths.go b/typelen/lengths.go index accb198..dbab107 100644 --- a/typelen/lengths.go +++ b/typelen/lengths.go @@ -13,7 +13,7 @@ const ( Count = 1 Enum16 = 1 Enum32 = 2 - Eui48 = 3 + Eui48 = 4 Float32 = 2 Int16 = 1 Int32 = 2 From 290a60870db57fca99ca6b4fcd0bb559152c5659 Mon Sep 17 00:00:00 2001 From: andig Date: Thu, 4 Jul 2019 21:20:01 +0200 Subject: [PATCH 2/2] Add tests --- impl/impl_test.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/impl/impl_test.go b/impl/impl_test.go index 022960f..dc20961 100644 --- a/impl/impl_test.go +++ b/impl/impl_test.go @@ -1,8 +1,14 @@ package impl import ( - "github.com/crabmusket/gosunspec/spi" + "encoding/binary" + "math" "testing" + + sunspec "github.com/crabmusket/gosunspec" + "github.com/crabmusket/gosunspec/smdx" + "github.com/crabmusket/gosunspec/spi" + "github.com/crabmusket/gosunspec/typelabel" ) func TestCompletePointInterface(t *testing.T) { @@ -16,3 +22,74 @@ func TestCompleteDevice(t *testing.T) { func TestCompleteArray(t *testing.T) { _ = spi.ArraySPI((&array{})) } + +func TestNotImplemented(t *testing.T) { + cases := []struct { + e bool + v interface{} + }{ + {false, float32(0)}, + {true, math.Float32frombits(0x7fc00000)}, + {false, int16(0)}, + {false, int32(0)}, + {false, int64(0)}, + {true, int16(-0x8000)}, + {true, int32(-0x80000000)}, + {true, int64(-0x8000000000000000)}, + {false, uint16(0)}, + {false, uint32(0)}, + {false, uint64(0)}, + {true, uint16(0xFFFF)}, + {true, uint32(0xFFFFFFFF)}, + {true, uint64(0xFFFFFFFFFFFFFFFF)}, + {false, sunspec.Ipaddr{0xFF, 0xFF, 0xFF, 0xFF}}, + {false, sunspec.Ipv6addr{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}, + {true, sunspec.Ipaddr{0, 0, 0, 0}}, + {true, sunspec.Ipv6addr{0, 0, 0, 0, 0, 0}}, + {false, sunspec.Eui48{0, 0, 0, 0, 0, 0}}, + {true, sunspec.Eui48{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}, + {false, sunspec.Bitfield16(0)}, + {false, sunspec.Bitfield32(0)}, + {true, sunspec.Bitfield16(0xFFFF)}, + {true, sunspec.Bitfield32(0xFFFFFFFF)}, + {false, sunspec.Enum16(0)}, + {false, sunspec.Enum32(0)}, + {true, sunspec.Enum16(0xFFFF)}, + {true, sunspec.Enum32(0xFFFFFFFF)}, + } + + for _, c := range cases { + p := point{ + err: nil, + value: c.v, + } + + if c.e != p.NotImplemented() { + t.Errorf("expected %v, got %v", c.e, c.v) + } + + if v, ok := p.Value().(sunspec.NotImplemented); !ok { + t.Errorf("expected sunspec.NotImplemented, got %v", v) + } + } +} + +func TestMarshalEui48(t *testing.T) { + p := point{ + err: nil, + smdx: &smdx.PointElement{ + Type: typelabel.Eui48, + }, + } + + p.Unmarshal([]byte{1, 2, 3, 4, 5, 6, 7, 8}) + + v := p.Value().(sunspec.Eui48) + if binary.BigEndian.Uint64(v[:]) != 0x0102030405060708 { + t.Errorf("unexpected value result, got %v", v) + } + + if v := p.MarshalXML(); v != "03:04:05:06:07:08" { + t.Errorf("unexpected xml result, got %v", v) + } +}