From d001e55ed0c650fc7f1faa80cdcb440ecc2a0a44 Mon Sep 17 00:00:00 2001 From: Xantios Krugor Date: Mon, 12 Aug 2024 12:41:54 +0200 Subject: [PATCH] Make UDP connection timeout configurable. (#238) --- cmd/chirpstack-gateway-bridge/cmd/configfile.go | 6 ++++++ cmd/chirpstack-gateway-bridge/cmd/root.go | 1 + internal/backend/semtechudp/backend.go | 3 ++- internal/backend/semtechudp/registry.go | 9 +++------ internal/config/config.go | 7 ++++--- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/cmd/chirpstack-gateway-bridge/cmd/configfile.go b/cmd/chirpstack-gateway-bridge/cmd/configfile.go index 94d85a98..0eeb9e9d 100644 --- a/cmd/chirpstack-gateway-bridge/cmd/configfile.go +++ b/cmd/chirpstack-gateway-bridge/cmd/configfile.go @@ -88,6 +88,12 @@ type="{{ .Backend.Type }}" # the time would otherwise be unset. fake_rx_time={{ .Backend.SemtechUDP.FakeRxTime }} + # Connection timeout duration + # + # ChirpStack Gateway Bridge keeps a list of connected gateways. If a gateway does not send any + # UDP data within the configured timeout, then ChirpStack Gateway Bridge will consider the gateway + # disconnected and it will unsubscribe from the gateway MQTT topic and cleanup the UDP docket. + connection_timeout_duration={{ .Backend.SemtechUDP.CleanupDuration }} # ChirpStack Concentratord backend. [backend.concentratord] diff --git a/cmd/chirpstack-gateway-bridge/cmd/root.go b/cmd/chirpstack-gateway-bridge/cmd/root.go index 5ad16bde..aa09c2b4 100644 --- a/cmd/chirpstack-gateway-bridge/cmd/root.go +++ b/cmd/chirpstack-gateway-bridge/cmd/root.go @@ -39,6 +39,7 @@ func init() { viper.SetDefault("general.log_level", 4) viper.SetDefault("backend.type", "semtech_udp") viper.SetDefault("backend.semtech_udp.udp_bind", "0.0.0.0:1700") + viper.SetDefault("backend.semtech_udp.cleanup_duration", time.Minute) viper.SetDefault("backend.concentratord.crc_check", true) viper.SetDefault("backend.concentratord.event_url", "ipc:///tmp/concentratord_event") diff --git a/internal/backend/semtechudp/backend.go b/internal/backend/semtechudp/backend.go index 14128a68..41bb3b05 100644 --- a/internal/backend/semtechudp/backend.go +++ b/internal/backend/semtechudp/backend.go @@ -67,7 +67,8 @@ func NewBackend(conf config.Config) (*Backend, error) { conn: conn, udpSendChan: make(chan udpPacket), gateways: gateways{ - gateways: make(map[lorawan.EUI64]gateway), + gateways: make(map[lorawan.EUI64]gateway), + cleanupDuration: time.Duration(conf.Backend.SemtechUDP.CleanupDuration), }, fakeRxTime: conf.Backend.SemtechUDP.FakeRxTime, skipCRCCheck: conf.Backend.SemtechUDP.SkipCRCCheck, diff --git a/internal/backend/semtechudp/registry.go b/internal/backend/semtechudp/registry.go index d1e91b37..ce483c0e 100644 --- a/internal/backend/semtechudp/registry.go +++ b/internal/backend/semtechudp/registry.go @@ -16,10 +16,6 @@ var ( errGatewayDoesNotExist = errors.New("gateway does not exist") ) -// gatewayCleanupDuration contains the duration after which the gateway is -// cleaned up from the registry after no activity -var gatewayCleanupDuration = -1 * time.Minute - // gateway contains a connection and meta-data for a gateway connection. type gateway struct { stats *stats.Collector @@ -31,7 +27,8 @@ type gateway struct { // gateways contains the gateways registry. type gateways struct { sync.RWMutex - gateways map[lorawan.EUI64]gateway + gateways map[lorawan.EUI64]gateway + cleanupDuration time.Duration subscribeEventFunc func(events.Subscribe) } @@ -82,7 +79,7 @@ func (c *gateways) cleanup() error { defer c.Unlock() for gatewayID := range c.gateways { - if c.gateways[gatewayID].lastSeen.Before(time.Now().Add(gatewayCleanupDuration)) { + if c.gateways[gatewayID].lastSeen.Before(time.Now().Add(c.cleanupDuration)) { disconnectCounter().Inc() if c.subscribeEventFunc != nil { diff --git a/internal/config/config.go b/internal/config/config.go index 70d42f2a..d201bca4 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -21,9 +21,10 @@ type Config struct { Type string `mapstructure:"type"` SemtechUDP struct { - UDPBind string `mapstructure:"udp_bind"` - SkipCRCCheck bool `mapstructure:"skip_crc_check"` - FakeRxTime bool `mapstructure:"fake_rx_time"` + UDPBind string `mapstructure:"udp_bind"` + SkipCRCCheck bool `mapstructure:"skip_crc_check"` + FakeRxTime bool `mapstructure:"fake_rx_time"` + CleanupDuration int `mapstructure:"connection_timeout_duration"` } `mapstructure:"semtech_udp"` BasicStation struct {