Skip to content

Commit

Permalink
Added auto-send interval to the set-listener API function and control…
Browse files Browse the repository at this point in the history
…ler message (cf. #21)
  • Loading branch information
twystd committed Oct 2, 2024
1 parent 8051439 commit c26b4fb
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 21 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

### Added
1. Added _interval_ parameter to _set-listener_ to set auto-send interval.


## [0.8.9](https://github.com/uhppoted/uhppote-core/releases/tag/v0.8.9) - 2024-09-06

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ Retrieves the IPv4 address of the host configured to receive events from the con

#### `SetListener`

Sets the IPv4 address of the host to receive events from the controller.
Sets the IPv4 address and port of the host to receive events from the controller, as well as the auto-send interval (the
auto-send interval is the interval at which the controller will repeatedly send the most recent event).

#### `GetTime`

Expand Down
13 changes: 6 additions & 7 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
# TODO

- [x] TCP/IP protocol (cf. https://github.com/uhppoted/uhppote-core/issues/17)
- [x] Update to Go 1.23 (cf. https://github.com/uhppoted/uhppoted/issues/53)
- [x] Add timezone to NewDevice
- [x] `put-card`: error on bad card numbers (0,0xffffffff,0x00ffffff)
- [x] Rework any remaining Date pointers to rather use IsZero
- [x] set-event-listener: add listen interval (cf. https://github.com/uhppoted/uhppote-core/issues/21)
- [x] set-event-listener
- [x] CHANGELOG
- [x] README


- [ ] Rework any remaining DateTime pointers to rather use IsZero
- [ ] Rework any remaining Time pointers
- (?) Replace (* UHPPOTE) in API functions with non-pointer version
- [x] `dump`
- [ ] logging: identify UDP/TCP packets

## TODO

Expand Down
1 change: 1 addition & 0 deletions messages/set_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type SetListenerRequest struct {
MsgType types.MsgType `uhppote:"value:0x90"`
SerialNumber types.SerialNumber `uhppote:"offset:4"`
AddrPort netip.AddrPort `uhppote:"offset:8"`
Interval uint8 `uhppote:"offset:14"`
}

type SetListenerResponse struct {
Expand Down
6 changes: 4 additions & 2 deletions messages/set_listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

func TestMarshalSetListenerRequest(t *testing.T) {
expected := []byte{
0x17, 0x90, 0x00, 0x00, 0x2D, 0x55, 0x39, 0x19, 0xc0, 0xa8, 0x01, 0x64, 0x40, 0x9c, 0x00, 0x00,
0x17, 0x90, 0x00, 0x00, 0x2D, 0x55, 0x39, 0x19, 0xc0, 0xa8, 0x01, 0x64, 0x40, 0x9c, 0x0d, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Expand All @@ -18,6 +18,7 @@ func TestMarshalSetListenerRequest(t *testing.T) {
request := SetListenerRequest{
SerialNumber: 423187757,
AddrPort: netip.MustParseAddrPort("192.168.1.100:40000"),
Interval: 13,
}

if m, err := codec.Marshal(request); err != nil {
Expand All @@ -29,7 +30,7 @@ func TestMarshalSetListenerRequest(t *testing.T) {

func TestFactoryUnmarshalSetListenerRequest(t *testing.T) {
message := []byte{
0x17, 0x90, 0x00, 0x00, 0x2D, 0x55, 0x39, 0x19, 0xc0, 0xa8, 0x01, 0x64, 0x40, 0x9c, 0x00, 0x00,
0x17, 0x90, 0x00, 0x00, 0x2D, 0x55, 0x39, 0x19, 0xc0, 0xa8, 0x01, 0x64, 0x40, 0x9c, 0x0d, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Expand All @@ -39,6 +40,7 @@ func TestFactoryUnmarshalSetListenerRequest(t *testing.T) {
MsgType: 0x90,
SerialNumber: 423187757,
AddrPort: netip.MustParseAddrPort("192.168.1.100:40000"),
Interval: 13,
}

request, err := UnmarshalRequest(message)
Expand Down
12 changes: 9 additions & 3 deletions uhppote/iuhppote.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@ type IUHPPOTE interface {
SetAddress(deviceID uint32, address, mask, gateway net.IP) (*types.Result, error)
GetListener(deviceID uint32) (netip.AddrPort, error)

// Sets the controller event listener address:port.
// Sets the controller event listener address:port and auto-send interval.
//
// The address must be either a valid IPv4 address and the port may not be 0 or
// 0.0.0.0:0.
// Returns true if the controller event listener address was set.
SetListener(deviceID uint32, address netip.AddrPort) (bool, error)
//
// The interval is the interval in seconds at which the controller will repeatedly
// send the most recent event (in addition to events sent as as they occur). A zero
// interval (the default) will only send events on occurrence.
//
// Returns true if the controller event listener address was set, error if something
// the address:port was invalid or the controller did not respohd.
SetListener(deviceID uint32, address netip.AddrPort, interval uint8) (bool, error)

GetTime(deviceID uint32) (*types.Time, error)
SetTime(deviceID uint32, datetime time.Time) (*types.Time, error)
Expand Down
14 changes: 13 additions & 1 deletion uhppote/set_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,18 @@ import (
"github.com/uhppoted/uhppote-core/types"
)

func (u *uhppote) SetListener(controller uint32, address netip.AddrPort) (bool, error) {
// Sets the controller event listener address:port and auto-send interval.
//
// The address must be either a valid IPv4 address and the port may not be 0 or
// 0.0.0.0:0.
//
// The interval is the interval in seconds at which the controller will repeatedly
// send the most recent event (in addition to events sent as as they occur). A zero interval
// (the default) will only send events on occurrence.
//
// Returns true if the controller event listener address was set, error if something
// the address:port was invalid or the controller did not respohd.
func (u *uhppote) SetListener(controller uint32, address netip.AddrPort, interval uint8) (bool, error) {
if controller == 0 {
return false, fmt.Errorf("invalid device ID (%v)", controller)
}
Expand All @@ -24,6 +35,7 @@ func (u *uhppote) SetListener(controller uint32, address netip.AddrPort) (bool,
request := messages.SetListenerRequest{
SerialNumber: types.SerialNumber(controller),
AddrPort: address,
Interval: interval,
}

if reply, err := sendto[messages.SetListenerResponse](u, controller, request); err != nil {
Expand Down
14 changes: 7 additions & 7 deletions uhppote/set_listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestSetListener(t *testing.T) {
},
}

if ok, err := u.SetListener(405419896, netip.MustParseAddrPort("192.168.1.100:60001")); err != nil {
if ok, err := u.SetListener(405419896, netip.MustParseAddrPort("192.168.1.100:60001"), 13); err != nil {
t.Errorf("unexpected error (%v)", err)
} else if !ok {
t.Errorf("invalid response - expected:%v, got:%v", true, ok)
Expand All @@ -47,7 +47,7 @@ func TestSetListenerWithANYAddr(t *testing.T) {
},
}

if ok, err := u.SetListener(405419896, netip.MustParseAddrPort("0.0.0.0:0")); err != nil {
if ok, err := u.SetListener(405419896, netip.MustParseAddrPort("0.0.0.0:0"), 13); err != nil {
t.Errorf("unexpected error (%v)", err)
} else if !ok {
t.Errorf("invalid response - expected:%v, got:%v", true, ok)
Expand All @@ -70,7 +70,7 @@ func TestSetListenerWithResponseFromIncorrectController(t *testing.T) {
},
}

if ok, err := u.SetListener(405419896, netip.MustParseAddrPort("192.168.1.100:60001")); err == nil {
if ok, err := u.SetListener(405419896, netip.MustParseAddrPort("192.168.1.100:60001"), 13); err == nil {
t.Errorf("expected 'invalid controller' error, got %v", err)
} else if fmt.Sprintf("%v", err) != "invalid controller ID - expected:405419896, got:423187757" {
t.Errorf("expected 'woot', got:%v", err)
Expand All @@ -82,23 +82,23 @@ func TestSetListenerWithResponseFromIncorrectController(t *testing.T) {
func TestSetListenerWithInvalidDeviceID(t *testing.T) {
u := uhppote{}

if _, err := u.SetListener(0, netip.MustParseAddrPort("192.168.1.100:60001")); err == nil {
if _, err := u.SetListener(0, netip.MustParseAddrPort("192.168.1.100:60001"), 13); err == nil {
t.Errorf("Expected 'invalid device ID' error, got %v", err)
}
}

func TestSetListenerWithInvalidAddrPort(t *testing.T) {
u := uhppote{}

if _, err := u.SetListener(405419896, netip.AddrPort{}); !errors.Is(err, ErrInvalidListenerAddress) {
if _, err := u.SetListener(405419896, netip.AddrPort{}, 13); !errors.Is(err, ErrInvalidListenerAddress) {
t.Errorf("Expected 'invalid listener address' error, got %v", err)
}
}

func TestSetListenerWithIPv6Address(t *testing.T) {
u := uhppote{}

if _, err := u.SetListener(405419896, netip.MustParseAddrPort("[2001:db8::68]:60001")); err == nil {
if _, err := u.SetListener(405419896, netip.MustParseAddrPort("[2001:db8::68]:60001"), 13); err == nil {
t.Errorf("Expected 'invalid listener address: [2001:db8::68]:60001', got %v", err)
} else if fmt.Sprintf("%v", err) != "invalid listener address: [2001:db8::68]:60001" {
t.Errorf("Expected 'invalid listener address: [2001:db8::68]:60001', got %v", err)
Expand All @@ -108,7 +108,7 @@ func TestSetListenerWithIPv6Address(t *testing.T) {
func TestSetListenerWithInvalidPort(t *testing.T) {
u := uhppote{}

if _, err := u.SetListener(405419896, netip.MustParseAddrPort("192.168.1.100:0")); err == nil {
if _, err := u.SetListener(405419896, netip.MustParseAddrPort("192.168.1.100:0"), 13); err == nil {
t.Errorf("Expected 'invalid listener address: 192.168.1.100:0', got %v", err)
} else if fmt.Sprintf("%v", err) != "invalid listener address: 192.168.1.100:0" {
t.Errorf("Expected 'invalid listener address: 192.168.1.100:0', got %v", err)
Expand Down

0 comments on commit c26b4fb

Please sign in to comment.