Skip to content

Commit

Permalink
Add functionality for removing nodes and fmt.
Browse files Browse the repository at this point in the history
  • Loading branch information
pwood committed Jan 13, 2021
1 parent e8df774 commit 6493620
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 10 deletions.
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ module github.com/shimmeringbee/zstack
go 1.14

require (
github.com/shimmeringbee/bytecodec v0.0.0-20201107142444-94bb5c0baaee
github.com/shimmeringbee/bytecodec v0.0.0-20210113154719-e97672fe9012
github.com/shimmeringbee/logwrap v0.0.0-20201104114416-23aeb26f66f1
github.com/shimmeringbee/retry v0.0.0-20201009192801-17b4f327c3e1
github.com/shimmeringbee/unpi v0.0.0-20210111165207-f0210c6942fc
github.com/shimmeringbee/zigbee v0.0.0-20201027194100-4e53cafc0f7a
github.com/stretchr/testify v1.6.1
github.com/shimmeringbee/unpi v0.0.0-20210111171128-10074b5edd8f
github.com/shimmeringbee/zigbee v0.0.0-20210113204558-b0b1b8711592
github.com/stretchr/testify v1.7.0
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
17 changes: 11 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv
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/shimmeringbee/bytecodec v0.0.0-20200216120857-49d677293817/go.mod h1:J/gvzi9IgGBHP1cBn++bqJ4tchSbgS10N2lmGMlqD3M=
github.com/shimmeringbee/bytecodec v0.0.0-20201107142444-94bb5c0baaee h1:LGPf3nQB0b+k/zxaSPqwcW1Zd3cBGcEqREwqT7CWmw8=
github.com/shimmeringbee/bytecodec v0.0.0-20201107142444-94bb5c0baaee/go.mod h1:WYnxfxTJ45UQ+xeAuuTSIalcEepgP8Rb7T/OhCaDdgo=
github.com/shimmeringbee/bytecodec v0.0.0-20210111165458-877359ca1003/go.mod h1:iqI5PkiqY+Xq6Hu22TNhepAY00iJCfk9jiXKBUrMSQQ=
github.com/shimmeringbee/bytecodec v0.0.0-20210113154719-e97672fe9012 h1:evpXaVtlNYHk8kU5DzFZIVe2X2ZRe9cgAtzHd1ktjjU=
github.com/shimmeringbee/bytecodec v0.0.0-20210113154719-e97672fe9012/go.mod h1:WYnxfxTJ45UQ+xeAuuTSIalcEepgP8Rb7T/OhCaDdgo=
github.com/shimmeringbee/logwrap v0.0.0-20201104114416-23aeb26f66f1 h1:HWCH7L4EyiipHROSw0iyPG0Nv9YUZHkYBGjo3BHCnko=
github.com/shimmeringbee/logwrap v0.0.0-20201104114416-23aeb26f66f1/go.mod h1:NBAcZCUl6aFOGnWTs8m67EUAmWFZXRhoRQf5nknY8W0=
github.com/shimmeringbee/retry v0.0.0-20201009192801-17b4f327c3e1 h1:XHZWCYRj+2lAwQhchW+SGbSeF/gTpZwROonbyT9u9A4=
github.com/shimmeringbee/retry v0.0.0-20201009192801-17b4f327c3e1/go.mod h1:FFeFkkqdD9vdDFr2la9PkSTQr6qgU9aBiGU3QKn8ZKY=
github.com/shimmeringbee/unpi v0.0.0-20201216190504-55241dd5fdcf h1:i6HBAOrD/mx8KMyM+THks3+w/qOr6zmuTWo2/fG91vs=
github.com/shimmeringbee/unpi v0.0.0-20201216190504-55241dd5fdcf/go.mod h1:iAt5R5HT+VC7B9U77uBmN5Z6+DJo4U0z6ag68NH2mMw=
github.com/shimmeringbee/unpi v0.0.0-20210111165207-f0210c6942fc h1:NqnGsfB3x2yJHTGmCh05ns6P0fRt+0llHpXxiR5w9Us=
github.com/shimmeringbee/unpi v0.0.0-20210111165207-f0210c6942fc/go.mod h1:iAt5R5HT+VC7B9U77uBmN5Z6+DJo4U0z6ag68NH2mMw=
github.com/shimmeringbee/zigbee v0.0.0-20201027194100-4e53cafc0f7a h1:PNZqpjc7ouHQ1MKqerPNNeLOcTsXWZ0ZF9avU8LG9Es=
github.com/shimmeringbee/zigbee v0.0.0-20201027194100-4e53cafc0f7a/go.mod h1:GMA6rVpzvUK16cZwi8uW11JUTx8xUGOk5DbkXYWvm/8=
github.com/shimmeringbee/unpi v0.0.0-20210111171128-10074b5edd8f h1:rLLdpe771s3ImhjNl+Bop1FOjtDcwVcEDYGBXjnHOGM=
github.com/shimmeringbee/unpi v0.0.0-20210111171128-10074b5edd8f/go.mod h1:hOrncW6hd26Z18eayp99i7hNKj0aHtUx1SxXT49aEsk=
github.com/shimmeringbee/zigbee v0.0.0-20210113202023-651b51432b13 h1:Zlu+99+PDDvkWAJwy2SvtCb+NKuVRAJ7fVBZ9J3gm6o=
github.com/shimmeringbee/zigbee v0.0.0-20210113202023-651b51432b13/go.mod h1:GMA6rVpzvUK16cZwi8uW11JUTx8xUGOk5DbkXYWvm/8=
github.com/shimmeringbee/zigbee v0.0.0-20210113204558-b0b1b8711592 h1:iD4w6TAkFqNoFk2WSUnjjD5kuFL4pf7ZnRsyykSKVIA=
github.com/shimmeringbee/zigbee v0.0.0-20210113204558-b0b1b8711592/go.mod h1:GMA6rVpzvUK16cZwi8uW11JUTx8xUGOk5DbkXYWvm/8=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand All @@ -31,6 +34,8 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
4 changes: 4 additions & 0 deletions messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ func registerMessages(l *Library) {

l.Add(SREQ, ZDO, ZDOMgmtPermitJoinRequestID, ZDOMgmtPermitJoinRequest{})
l.Add(SRSP, ZDO, ZDOMgmtPermitJoinRequestReplyID, ZDOMgmtPermitJoinRequestReply{})

l.Add(SREQ, ZDO, ZdoMgmtLeaveReqID, ZdoMgmtLeaveReq{})
l.Add(SRSP, ZDO, ZdoMgmtLeaveReqReplyID, ZdoMgmtLeaveReqReply{})
l.Add(AREQ, ZDO, ZdoMgmtLeaveRspID, ZdoMgmtLeaveRsp{})
}

type ZStackStatus uint8
Expand Down
42 changes: 42 additions & 0 deletions messages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,4 +723,46 @@ func Test_registerMessages(t *testing.T) {
assert.True(t, found)
assert.Equal(t, reflect.TypeOf(ZDOMgmtPermitJoinRequestReply{}), ty)
})

t.Run("ZdoMgmtLeaveReq", func(t *testing.T) {
identity, found := ml.GetByObject(&ZdoMgmtLeaveReq{})

assert.True(t, found)
assert.Equal(t, SREQ, identity.MessageType)
assert.Equal(t, ZDO, identity.Subsystem)
assert.Equal(t, uint8(0x34), identity.CommandID)

ty, found := ml.GetByIdentifier(SREQ, ZDO, 0x34)

assert.True(t, found)
assert.Equal(t, reflect.TypeOf(ZdoMgmtLeaveReq{}), ty)
})

t.Run("ZdoMgmtLeaveReqReply", func(t *testing.T) {
identity, found := ml.GetByObject(&ZdoMgmtLeaveReqReply{})

assert.True(t, found)
assert.Equal(t, SRSP, identity.MessageType)
assert.Equal(t, ZDO, identity.Subsystem)
assert.Equal(t, uint8(0x34), identity.CommandID)

ty, found := ml.GetByIdentifier(SRSP, ZDO, 0x34)

assert.True(t, found)
assert.Equal(t, reflect.TypeOf(ZdoMgmtLeaveReqReply{}), ty)
})

t.Run("ZdoMgmtLeaveRsp", func(t *testing.T) {
identity, found := ml.GetByObject(&ZdoMgmtLeaveRsp{})

assert.True(t, found)
assert.Equal(t, AREQ, identity.MessageType)
assert.Equal(t, ZDO, identity.Subsystem)
assert.Equal(t, uint8(0xb4), identity.CommandID)

ty, found := ml.GetByIdentifier(AREQ, ZDO, 0xb4)

assert.True(t, found)
assert.Equal(t, reflect.TypeOf(ZdoMgmtLeaveRsp{}), ty)
})
}
54 changes: 54 additions & 0 deletions node_remove.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package zstack

import (
"context"
"github.com/shimmeringbee/zigbee"
)

func (z *ZStack) RemoveNode(ctx context.Context, nodeAddress zigbee.IEEEAddress) error {
networkAddress, err := z.ResolveNodeNWKAddress(ctx, nodeAddress)

if err != nil {
return nil
}

request := ZdoMgmtLeaveReq{
NetworkAddress: networkAddress,
IEEEAddress: nodeAddress,
RemoveChildren: false,
}

_, err = z.nodeRequest(ctx, &request, &ZdoMgmtLeaveReqReply{}, &ZdoMgmtLeaveRsp{}, func(i interface{}) bool {
msg := i.(*ZdoMgmtLeaveRsp)
return msg.SourceAddress == networkAddress
})

return err
}

type ZdoMgmtLeaveReq struct {
NetworkAddress zigbee.NetworkAddress
IEEEAddress zigbee.IEEEAddress
RemoveChildren bool
}

const ZdoMgmtLeaveReqID uint8 = 0x34

type ZdoMgmtLeaveReqReply GenericZStackStatus

func (r ZdoMgmtLeaveReqReply) WasSuccessful() bool {
return r.Status == ZSuccess
}

const ZdoMgmtLeaveReqReplyID uint8 = 0x34

type ZdoMgmtLeaveRsp struct {
SourceAddress zigbee.NetworkAddress
Status ZStackStatus
}

func (r ZdoMgmtLeaveRsp) WasSuccessful() bool {
return r.Status == ZSuccess
}

const ZdoMgmtLeaveRspID uint8 = 0xb4
112 changes: 112 additions & 0 deletions node_remove_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package zstack

import (
"context"
"github.com/shimmeringbee/bytecodec"
. "github.com/shimmeringbee/unpi"
unpiTest "github.com/shimmeringbee/unpi/testing"
"github.com/shimmeringbee/zigbee"
"github.com/stretchr/testify/assert"
"testing"
"time"
)

func TestZStack_RemoveNode(t *testing.T) {
t.Run("returns an success on query, response for requested network address is received", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()

unpiMock := unpiTest.NewMockAdapter()
zstack := New(unpiMock, NewNodeTable())
defer unpiMock.Stop()

call := unpiMock.On(SREQ, ZDO, ZdoMgmtLeaveReqReplyID).Return(Frame{
MessageType: SRSP,
Subsystem: ZDO,
CommandID: ZdoMgmtLeaveReqReplyID,
Payload: []byte{0x00},
})

go func() {
time.Sleep(10 * time.Millisecond)
unpiMock.InjectOutgoing(Frame{
MessageType: AREQ,
Subsystem: ZDO,
CommandID: ZdoMgmtLeaveRspID,
Payload: []byte{0x00, 0x40, 0x00},
})
}()

zstack.nodeTable.addOrUpdate(zigbee.IEEEAddress(1), zigbee.NetworkAddress(0x4000))

err := zstack.RemoveNode(ctx, zigbee.IEEEAddress(1))
assert.NoError(t, err)

leaveReq := ZdoMgmtLeaveReq{}
bytecodec.Unmarshal(call.CapturedCalls[0].Frame.Payload, &leaveReq)

assert.Equal(t, zigbee.IEEEAddress(1), leaveReq.IEEEAddress)
assert.Equal(t, zigbee.NetworkAddress(0x4000), leaveReq.NetworkAddress)
assert.False(t, leaveReq.RemoveChildren)

unpiMock.AssertCalls(t)
})
}

func Test_RemoveMessages(t *testing.T) {
t.Run("verify ZdoMgmtLeaveReq marshals", func(t *testing.T) {
req := ZdoMgmtLeaveReq{
NetworkAddress: 0x1234,
IEEEAddress: zigbee.IEEEAddress(0x8899aabbccddeeff),
RemoveChildren: true,
}

data, err := bytecodec.Marshal(req)

assert.NoError(t, err)
assert.Equal(t, []byte{0x34, 0x12, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x01}, data)
})

t.Run("verify ZdoMgmtLeaveReqReply marshals", func(t *testing.T) {
req := ZdoMgmtLeaveReqReply{
Status: 1,
}

data, err := bytecodec.Marshal(req)

assert.NoError(t, err)
assert.Equal(t, []byte{0x01}, data)
})

t.Run("ZdoMgmtLeaveReqReply returns true if success", func(t *testing.T) {
g := ZdoMgmtLeaveReqReply{Status: ZSuccess}
assert.True(t, g.WasSuccessful())
})

t.Run("ZdoMgmtLeaveReqReply returns false if not success", func(t *testing.T) {
g := ZdoMgmtLeaveReqReply{Status: ZFailure}
assert.False(t, g.WasSuccessful())
})

t.Run("verify ZdoMgmtLeaveRsp marshals", func(t *testing.T) {
req := ZdoMgmtLeaveRsp{
SourceAddress: zigbee.NetworkAddress(0x2000),
Status: 1,
}

data, err := bytecodec.Marshal(req)

assert.NoError(t, err)
assert.Equal(t, []byte{0x00, 0x20, 0x01}, data)
})

t.Run("ZdoMgmtLeaveRsp returns true if success", func(t *testing.T) {
g := ZdoMgmtLeaveRsp{Status: ZSuccess}
assert.True(t, g.WasSuccessful())
})

t.Run("ZdoMgmtLeaveRsp returns false if not success", func(t *testing.T) {
g := ZdoMgmtLeaveRsp{Status: ZFailure}
assert.False(t, g.WasSuccessful())
})
}
2 changes: 2 additions & 0 deletions zstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ type ZStack struct {
logger logwrap.Logger
}

var _ zigbee.Provider = (*ZStack)(nil)

type JoinState uint8

const (
Expand Down

0 comments on commit 6493620

Please sign in to comment.