Modbus: validate protocol (#15912)

This commit is contained in:
andig 2024-09-05 20:07:40 +02:00 • committed by GitHub
parent 16107f9c2b
commit 333bcfab24
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -63,6 +63,7 @@ func (s *Settings) String() string {
type meterConnection struct {
meters.Connection
proto Protocol
*logger
}
@ -71,23 +72,28 @@ var (
mu sync.Mutex
)
func registeredConnection(key string, newConn meters.Connection) *meterConnection {
func registeredConnection(key string, proto Protocol, newConn meters.Connection) (*meterConnection, error) {
mu.Lock()
defer mu.Unlock()
if conn, ok := connections[key]; ok {
return conn
if conn.proto != proto {
return nil, fmt.Errorf("connection already registered with different protocol: %s", key)
}
return conn, nil
}
connection := &meterConnection{
Connection: newConn,
proto: proto,
logger: new(logger),
}
newConn.Logger(connection.logger)
connections[key] = connection
return connection
return connection, nil
}
// NewConnection creates physical modbus device from config
@ -111,8 +117,6 @@ func NewConnection(uri, device, comset string, baudrate int, proto Protocol, sla
}
func physicalConnection(proto Protocol, cfg Settings) (*meterConnection, error) {
var conn *meterConnection
if (cfg.Device != "") == (cfg.URI != "") {
return nil, errors.New("invalid modbus configuration: must have either uri or device")
}
@ -131,28 +135,24 @@ func physicalConnection(proto Protocol, cfg Settings) (*meterConnection, error)
}
if proto == Ascii {
conn = registeredConnection(cfg.Device, meters.NewASCII(cfg.Device, cfg.Baudrate, cfg.Comset))
return registeredConnection(cfg.Device, Ascii, meters.NewASCII(cfg.Device, cfg.Baudrate, cfg.Comset))
} else {
conn = registeredConnection(cfg.Device, meters.NewRTU(cfg.Device, cfg.Baudrate, cfg.Comset))
return registeredConnection(cfg.Device, Rtu, meters.NewRTU(cfg.Device, cfg.Baudrate, cfg.Comset))
}
}
if cfg.URI != "" {
cfg.URI = util.DefaultPort(cfg.URI, 502)
uri := util.DefaultPort(cfg.URI, 502)
switch proto {
case Udp:
conn = registeredConnection(cfg.URI, meters.NewRTUOverUDP(cfg.URI))
case Rtu:
conn = registeredConnection(cfg.URI, meters.NewRTUOverTCP(cfg.URI))
case Ascii:
conn = registeredConnection(cfg.URI, meters.NewASCIIOverTCP(cfg.URI))
default:
conn = registeredConnection(cfg.URI, meters.NewTCP(cfg.URI))
}
switch proto {
case Udp:
return registeredConnection(uri, Udp, meters.NewRTUOverUDP(uri))
case Rtu:
return registeredConnection(uri, Rtu, meters.NewRTUOverTCP(uri))
case Ascii:
return registeredConnection(uri, Ascii, meters.NewASCIIOverTCP(uri))
default:
return registeredConnection(uri, Tcp, meters.NewTCP(uri))
}
return conn, nil
}
// NewDevice creates physical modbus device from config