Skip to content

Commit

Permalink
Complete support for querying an endpoints description, closes #6.
Browse files Browse the repository at this point in the history
  • Loading branch information
pwood committed Feb 9, 2020
1 parent 45497de commit 1077a10
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 85 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ go 1.13
require (
github.com/shimmeringbee/bytecodec v0.0.0-20191116111328-f873abddc0ca
github.com/shimmeringbee/unpi v0.0.0-20200208214536-ae03ffed80df
github.com/shimmeringbee/zigbee v0.0.0-20200120203528-41c732360d3b
github.com/shimmeringbee/zigbee v0.0.0-20200209141444-4751de36c63a
github.com/stretchr/testify v1.4.0
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ github.com/shimmeringbee/zigbee v0.0.0-20191117130828-cab4fe16ac87 h1:Yi9tjP5tI8
github.com/shimmeringbee/zigbee v0.0.0-20191117130828-cab4fe16ac87/go.mod h1:WVZ5totAgMhUc1ubHym27LsKRnXv1MAiGyaDEs4dzak=
github.com/shimmeringbee/zigbee v0.0.0-20200120203528-41c732360d3b h1:t2oXaGn3t/PFHs4PhlDEkDdTXunyNC3b46ecqEmKxyE=
github.com/shimmeringbee/zigbee v0.0.0-20200120203528-41c732360d3b/go.mod h1:WVZ5totAgMhUc1ubHym27LsKRnXv1MAiGyaDEs4dzak=
github.com/shimmeringbee/zigbee v0.0.0-20200209141444-4751de36c63a h1:2arwf+RSJlxeyNuDwbfdvjC2Bhe9K0ZVvtvliT/m238=
github.com/shimmeringbee/zigbee v0.0.0-20200209141444-4751de36c63a/go.mod h1:WVZ5totAgMhUc1ubHym27LsKRnXv1MAiGyaDEs4dzak=
github.com/shimmeringbee/zstack v0.0.0-20191118220231-acddb74ca28e/go.mod h1:U7Upz3GOefZyV1IA28N3v/iY4MLBqkujTspCZr5mv6k=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
69 changes: 69 additions & 0 deletions node_endpoint_description.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package zstack

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

func (z *ZStack) QueryNodeEndpointDescription(ctx context.Context, networkAddress zigbee.NetworkAddress, endpoint byte) (zigbee.EndpointDescription, error) {
request := ZdoSimpleDescReq{
DestinationAddress: networkAddress,
OfInterestAddress: networkAddress,
Endpoint: endpoint,
}

resp, err := z.nodeRequest(ctx, &request, &ZdoSimpleDescReqReply{}, &ZdoSimpleDescRsp{}, func(i interface{}) bool {
msg := i.(*ZdoSimpleDescRsp)
return msg.OfInterestAddress == networkAddress && msg.Endpoint == endpoint
})

castResp, ok := resp.(*ZdoSimpleDescRsp)

if ok {
return zigbee.EndpointDescription{
Endpoint: castResp.Endpoint,
ProfileID: castResp.ProfileID,
DeviceID: castResp.DeviceID,
DeviceVersion: castResp.DeviceVersion,
InClusterList: castResp.InClusterList,
OutClusterList: castResp.OutClusterList,
}, nil
} else {
return zigbee.EndpointDescription{}, err
}
}

type ZdoSimpleDescReq struct {
DestinationAddress zigbee.NetworkAddress
OfInterestAddress zigbee.NetworkAddress
Endpoint byte
}

const ZdoSimpleDescReqID uint8 = 0x04

type ZdoSimpleDescReqReply GenericZStackStatus

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

const ZdoSimpleDescReqReplyID uint8 = 0x04

type ZdoSimpleDescRsp struct {
SourceAddress zigbee.NetworkAddress
Status ZStackStatus
OfInterestAddress zigbee.NetworkAddress
Length uint8
Endpoint byte
ProfileID uint16
DeviceID uint16
DeviceVersion uint8
InClusterList []zigbee.ZCLClusterID `bclength:"8"`
OutClusterList []zigbee.ZCLClusterID `bclength:"8"`
}

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

const ZdoSimpleDescRspID uint8 = 0x84
119 changes: 119 additions & 0 deletions node_endpoint_description_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
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 Test_QueryNodeEndpointDescription(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)
defer unpiMock.Stop()

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

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

endpoints, err := zstack.QueryNodeEndpointDescription(ctx, zigbee.NetworkAddress(0x4000), 0x01)
assert.NoError(t, err)
assert.Equal(t, zigbee.EndpointDescription{
Endpoint: 0x01,
ProfileID: 0x0101,
DeviceID: 1,
DeviceVersion: 2,
InClusterList: []zigbee.ZCLClusterID{0x0001},
OutClusterList: []zigbee.ZCLClusterID{0x0002},
}, endpoints)

unpiMock.AssertCalls(t)
})
}

func Test_SimpleDescriptionMessages(t *testing.T) {
t.Run("verify ZdoSimpleDescReq marshals", func(t *testing.T) {
req := ZdoSimpleDescReq{
DestinationAddress: zigbee.NetworkAddress(0x2000),
OfInterestAddress: zigbee.NetworkAddress(0x4000),
Endpoint: 0x08,
}

data, err := bytecodec.Marshall(req)

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

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

data, err := bytecodec.Marshall(req)

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

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

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

t.Run("verify ZdoSimpleDescRsp marshals", func(t *testing.T) {
req := ZdoSimpleDescRsp{
SourceAddress: zigbee.NetworkAddress(0x2000),
Status: 1,
OfInterestAddress: zigbee.NetworkAddress(0x4000),
Length: 0x0a,
Endpoint: 0x08,
ProfileID: 0x1234,
DeviceID: 0x5678,
DeviceVersion: 0,
InClusterList: []zigbee.ZCLClusterID{0x1234},
OutClusterList: []zigbee.ZCLClusterID{0x5678},
}

data, err := bytecodec.Marshall(req)

assert.NoError(t, err)
assert.Equal(t, []byte{0x00, 0x20, 0x01, 0x00, 0x40, 0x0a, 0x08, 0x34, 0x12, 0x78, 0x56, 0x00, 0x01, 0x34, 0x12, 0x01, 0x78, 0x56}, data)
})

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

t.Run("generic ZdoSimpleDescRsp returns false if not success", func(t *testing.T) {
g := ZdoSimpleDescRsp{Status:ZFailure}
assert.False(t, g.WasSuccessful())
})
}
30 changes: 0 additions & 30 deletions node_simple_description.go

This file was deleted.

54 changes: 0 additions & 54 deletions node_simple_description_test.go

This file was deleted.

0 comments on commit 1077a10

Please sign in to comment.